Fixed the build error for gcc-14
[platform/core/pim/contacts-service.git] / common / ctsvc_vcard.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19 #include <glib.h>
20 #include <errno.h>
21 #include <ctype.h>
22 #include <fcntl.h>
23 #include <unistd.h>
24 #include <sys/time.h>
25 #include <unicode/ucnv.h>
26 #include <unicode/ustring.h>
27 #include <tzplatform_config.h>
28 #include <limits.h>
29
30 #ifdef _CONTACTS_IPC_CLIENT
31 #include "ctsvc_client_ipc.h"
32 #endif
33
34 #include "contacts.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"
41
42 #define DEFAULT_ADDRESS_BOOK_ID 0
43
44 #define SMART_STRDUP(src) (src && *src) ? strdup(src) : NULL
45 #define CTSVC_VCARD_PHOTO_MAX_SIZE 1024*1024
46
47 /* LCOV_EXCL_START */
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; \
52         } \
53 } while (0)
54
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; \
59         } \
60 } while (0)
61 /* LCOV_EXCL_STOP */
62
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); \
68 } while (0)
69
70 enum {
71         CTSVC_VCARD_VER_NONE,
72         CTSVC_VCARD_VER_2_1,
73         CTSVC_VCARD_VER_3_0,
74         CTSVC_VCARD_VER_4_0,
75 };
76
77 enum {
78         CTSVC_VCARD_VALUE_NONE,
79         CTSVC_VCARD_VALUE_FN,
80         CTSVC_VCARD_VALUE_N,
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
117 };
118
119 enum {
120         CTSVC_VCARD_IMG_NONE,
121         CTSVC_VCARD_IMG_PNG,    /* Portable Network Graphics */
122         /* vcard  2.1 spec */
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 */
139 };
140
141 static const char *content_name[CTSVC_VCARD_VALUE_MAX] = {0};
142 const char *CTSVC_CRLF = "\r\n";
143
144 static int limit_size_of_photo = CTSVC_IMAGE_MAX_SIZE;
145
146 static void __ctsvc_vcard_initial(void)
147 {
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";
201         }
202 };
203
204 static int __ctsvc_vcard_append_str(char **buf, int *buf_size, int len, const char *str, bool need_conversion)
205 {
206         int len_temp = 0;
207         char *tmp = NULL;
208         const char *safe_str = SAFE_STR(str);
209         int str_len = 0;
210         bool need_realloc = false;
211
212         str_len = strlen(safe_str);
213         while ((*buf_size-len) < (str_len+1)) {
214                 *buf_size = *buf_size * 2;
215                 need_realloc = true;
216         }
217
218         if (need_realloc) {
219                 if (NULL == (tmp = realloc(*buf, *buf_size)))
220                         return -1;
221                 else
222                         *buf = tmp;
223         }
224
225         if (need_conversion) {
226                 const char *s = safe_str;
227                 char *r = (char *)(*buf+len);
228
229                 while (*s) {
230                         switch (*s) {
231 /* LCOV_EXCL_START */
232                         case '\r':
233                                 if (*(s+1) && '\n' == *(s+1)) {
234                                         s++;
235                                         *r = '\\';
236                                         r++;
237                                         *r = 'n';
238                                 } else {
239                                         *r = *s;
240                                 }
241                                 break;
242                         case '\n':
243                                 *r = '\\';
244                                 r++;
245                                 str_len++;
246                                 if (*buf_size < str_len+len+1) {
247                                         *buf_size = *buf_size * 2;
248                                         if (NULL == (tmp = realloc(*buf, *buf_size))) {
249                                                 return -1;
250                                         } else {
251                                                 *buf = tmp;
252                                                 r = (char *)(*buf+len+str_len);
253                                         }
254                                 }
255                                 *r = 'n';
256                                 break;
257 /* LCOV_EXCL_STOP */
258                         case ';':
259                         case ':':
260                         case ',':
261                         case '<':
262                         case '>':
263                         case '\\':
264                                 *r = '\\';
265                                 r++;
266                                 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))) {
271                                                 return -1;
272                                         } else {
273                                                 *buf = tmp;
274                                                 r = (char *)(*buf+len+str_len);
275                                         }
276                                 }
277 /* LCOV_EXCL_STOP */
278                                 *r = *s;
279                                 break;
280 /* LCOV_EXCL_START */
281                         case 0xA1:
282                                 if (*(s+1) && 0xAC == *(s+1)) { /* en/em backslash */
283                                         *r = '\\';
284                                         r++;
285                                         str_len++;
286                                         if (*buf_size < str_len+len+1) {
287                                                 *buf_size = *buf_size * 2;
288                                                 if (NULL == (tmp = realloc(*buf, *buf_size))) {
289                                                         return -1;
290                                                 } else {
291                                                         *buf = tmp;
292                                                         r = (char *)(*buf+len+str_len);
293                                                 }
294                                         }
295
296                                         *r = *s;
297                                         r++;
298                                         s++;
299                                         if (*buf_size < str_len+len+1) {
300                                                 *buf_size = *buf_size * 2;
301                                                 if (NULL == (tmp = realloc(*buf, *buf_size))) {
302                                                         return -1;
303                                                 } else {
304                                                         *buf = tmp;
305                                                         r = (char *)(*buf+len+str_len);
306                                                 }
307                                         }
308                                         *r = *s;
309                                 } else {
310                                         *r = *s;
311                                 }
312                                 break;
313                         case 0x81:
314                                 if (*(s+1) && 0x5F == *(s+1)) { /* en/em backslash */
315                                         *r = '\\';
316                                         r++;
317                                         str_len++;
318                                         if (*buf_size < str_len+len+1) {
319                                                 *buf_size = *buf_size * 2;
320                                                 if (NULL == (tmp = realloc(*buf, *buf_size))) {
321                                                         return -1;
322                                                 } else {
323                                                         *buf = tmp;
324                                                         r = (char *)(*buf+len+str_len);
325                                                 }
326                                         }
327
328                                         *r = *s;
329                                         r++;
330                                         s++;
331                                         if (*buf_size < str_len+len+1) {
332                                                 *buf_size = *buf_size * 2;
333                                                 if (NULL == (tmp = realloc(*buf, *buf_size))) {
334                                                         return -1;
335                                                 } else {
336                                                         *buf = tmp;
337                                                         r = (char *)(*buf+len+str_len);
338                                                 }
339                                         }
340                                         *r = *s;
341                                 } else {
342                                         *r = *s;
343                                 }
344                                 break;
345 /* LCOV_EXCL_STOP */
346                         default:
347                                 *r = *s;
348                                 break;
349                         }
350                         r++;
351                         s++;
352                 }
353                 len_temp = str_len;
354         } else {
355                 len_temp = snprintf(*buf+len, *buf_size-len+1, "%s", safe_str);
356         }
357         len += len_temp;
358         return len;
359 }
360
361 #define CTS_VCARD_FOLDING_LIMIT 75
362
363 static inline int __ctsvc_vcard_add_folding(char **buf, int *buf_size, int buf_len)
364 {
365         int char_len = 0;
366         char *buf_copy = NULL;
367         int len, result_len = 0;
368         char *r;
369         const char *s;
370         bool content_start = false;
371         bool encode_64 = false;
372
373         buf_copy = calloc(1, *buf_size);
374         if (NULL == buf_copy) {
375                 ERR("calloc() Fail"); /* LCOV_EXCL_LINE */
376                 return 0;
377         }
378
379         s = *buf;
380         r = buf_copy;
381         len = result_len;
382
383         while (*s) {
384                 if (*buf_size < result_len + 5) {
385                         char *tmp = NULL;
386                         *buf_size = *buf_size + 1000;
387                         if (NULL == (tmp = realloc(buf_copy, *buf_size))) {
388                                 free(buf_copy);
389                                 return -1;
390                         } else {
391                                 buf_copy = tmp;
392                                 r = (buf_copy + result_len);
393                         }
394                 }
395
396                 if (false == content_start) {
397                         if (':' == *s)
398                                 content_start = true;
399                         else if (STRING_EQUAL == strncmp(s, "ENCODING=BASE64", strlen("ENCODING=BASE64")))
400                                 encode_64 = true;
401                 }
402
403                 if ('\r' == *s) {
404                         len--;
405                 } else if ('\n' == *s) {
406                         len = -1;
407                         char_len = 0;
408                         content_start = false;
409                         encode_64 = false;
410                 }
411
412                 if (0 == char_len) {
413                         if (false == encode_64)
414                                 char_len = ctsvc_check_utf8(*s);
415
416                         if (CTS_VCARD_FOLDING_LIMIT <= len + char_len) {
417                                 *r = '\r';
418                                 r++;
419                                 *r = '\n';
420                                 r++;
421                                 *r = ' ';
422                                 r++;
423                                 len = 1;
424                                 result_len += 3;
425                         }
426                 }
427
428                 if (char_len)
429                         char_len--;
430
431                 *r = *s;
432                 r++;
433                 s++;
434                 len++;
435                 result_len++;
436         }
437         *r = '\0';
438         free(*buf);
439         *buf = buf_copy;
440         return result_len;
441 }
442
443 static inline int __ctsvc_vcard_append_name(ctsvc_list_s *names, char **buf, int *buf_size, int len)
444 {
445         char display[1024] = {0};
446         GList *cursor = names->records;
447         ctsvc_name_s *name;
448
449         RETV_IF(NULL == cursor, len);
450
451         name = cursor->data;
452
453         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_N]);
454
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);
466
467         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
468
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);
473 #endif
474                 if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == order) {
475                         snprintf(display, sizeof(display), "%s %s", name->first, name->last);
476                 } else {
477                         /* CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST */
478                         snprintf(display, sizeof(display), "%s, %s", name->last, name->first);
479                 }
480         } else {
481                 snprintf(display, sizeof(display), "%s%s", SAFE_STR(name->first), SAFE_STR(name->last));
482         }
483
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);
486
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);
490         }
491
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);
495         }
496
497
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);
501         }
502
503         return len;
504 }
505
506 static inline const char* __ctsvc_get_img_suffix(int type)
507 {
508         switch (type) {
509         case CTSVC_VCARD_IMG_TIFF:
510                 return "tiff";
511                 /* LCOV_EXCL_START */
512         case CTSVC_VCARD_IMG_GIF:
513                 return "gif";
514         case CTSVC_VCARD_IMG_PNG:
515                 return "png";
516         case CTSVC_VCARD_IMG_CGM:
517                 return "cgm";
518         case CTSVC_VCARD_IMG_WMF:
519                 return "wmf";
520         case CTSVC_VCARD_IMG_BMP:
521                 return "bmp";
522         case CTSVC_VCARD_IMG_MET:
523                 return "met";
524         case CTSVC_VCARD_IMG_PMB:
525                 return "pmb";
526         case CTSVC_VCARD_IMG_DIB:
527                 return "dib";
528         case CTSVC_VCARD_IMG_PICT:
529                 return "pict";
530         case CTSVC_VCARD_IMG_PDF:
531                 return "pdf";
532         case CTSVC_VCARD_IMG_PS:
533                 return "ps";
534         case CTSVC_VCARD_IMG_QTIME:
535                 return "qtime";
536         case CTSVC_VCARD_IMG_MPEG:
537                 return "mpeg";
538         case CTSVC_VCARD_IMG_MPEG2:
539                 return "mpeg2";
540         case CTSVC_VCARD_IMG_AVI:
541                 return "avi";
542                 /* LCOV_EXCL_STOP */
543         case CTSVC_VCARD_IMG_JPEG:
544         case CTSVC_VCARD_IMG_NONE:
545         default:
546                 return "jpeg";
547         }
548 }
549
550 static inline int __ctsvc_vcard_get_image_type(const char *val)
551 {
552         char *temp, *image_path, *result;
553         RETV_IF(NULL == val, CTSVC_VCARD_IMG_NONE);
554
555         image_path = strdup(val);
556         temp = image_path;
557         while (*temp) {
558                 *temp = tolower(*temp);
559                 temp++;
560         }
561
562         result = strstr(image_path, "jpeg");
563         if (result) {
564                 free(image_path);
565                 return CTSVC_VCARD_IMG_JPEG;
566         }
567
568         result = strstr(image_path, "jpg");
569         if (result) {
570                 free(image_path);
571                 return CTSVC_VCARD_IMG_JPEG;
572         }
573                 /* LCOV_EXCL_START */
574         result = strstr(image_path, "png");
575         if (result) {
576                 free(image_path);
577                 return CTSVC_VCARD_IMG_PNG;
578         }
579
580         result = strstr(image_path, "gif");
581         if (result) {
582                 free(image_path);
583                 return CTSVC_VCARD_IMG_GIF;
584         }
585
586         result = strstr(image_path, "tiff");
587         if (result) {
588                 free(image_path);
589                 return CTSVC_VCARD_IMG_TIFF;
590         }
591
592         result = strstr(image_path, "cgm");
593         if (result) {
594                 free(image_path);
595                 return CTSVC_VCARD_IMG_CGM;
596         }
597
598         result = strstr(image_path, "wmf");
599         if (result) {
600                 free(image_path);
601                 return CTSVC_VCARD_IMG_WMF;
602         }
603
604         result = strstr(image_path, "bmp");
605         if (result) {
606                 free(image_path);
607                 return CTSVC_VCARD_IMG_BMP;
608         }
609
610         result = strstr(image_path, "met");
611         if (result) {
612                 free(image_path);
613                 return CTSVC_VCARD_IMG_MET;
614         }
615
616         result = strstr(image_path, "pmb");
617         if (result) {
618                 free(image_path);
619                 return CTSVC_VCARD_IMG_PMB;
620         }
621
622         result = strstr(image_path, "dib");
623         if (result) {
624                 free(image_path);
625                 return CTSVC_VCARD_IMG_DIB;
626         }
627
628         result = strstr(image_path, "pict");
629         if (result) {
630                 free(image_path);
631                 return CTSVC_VCARD_IMG_PICT;
632         }
633
634         result = strstr(image_path, "pdf");
635         if (result) {
636                 free(image_path);
637                 return CTSVC_VCARD_IMG_PDF;
638         }
639
640         result = strstr(image_path, "ps");
641         if (result) {
642                 free(image_path);
643                 return CTSVC_VCARD_IMG_PS;
644         }
645
646         result = strstr(image_path, "qtime");
647         if (result) {
648                 free(image_path);
649                 return CTSVC_VCARD_IMG_QTIME;
650         }
651
652         result = strstr(image_path, "mpeg");
653         if (result) {
654                 free(image_path);
655                 return CTSVC_VCARD_IMG_MPEG;
656         }
657
658         result = strstr(image_path, "mpeg2");
659         if (result) {
660                 free(image_path);
661                 return CTSVC_VCARD_IMG_MPEG2;
662         }
663
664         result = strstr(image_path, "avi");
665         if (result) {
666                 free(image_path);
667                 return CTSVC_VCARD_IMG_AVI;
668         }
669
670         free(image_path);
671         return CTSVC_VCARD_IMG_NONE;
672                 /* LCOV_EXCL_STOP */
673 }
674
675 static inline const char* __ctsvc_get_image_type_str(int type)
676 {
677         switch (type) {
678         case CTSVC_VCARD_IMG_TIFF:
679                 return "TIFF";
680                 /* LCOV_EXCL_START */
681         case CTSVC_VCARD_IMG_GIF:
682                 return "GIF";
683         case CTSVC_VCARD_IMG_PNG:
684                 return "PNG";
685         case CTSVC_VCARD_IMG_CGM:
686                 return "CGM";
687         case CTSVC_VCARD_IMG_WMF:
688                 return "WMF";
689         case CTSVC_VCARD_IMG_BMP:
690                 return "BMP";
691         case CTSVC_VCARD_IMG_MET:
692                 return "MET";
693         case CTSVC_VCARD_IMG_PMB:
694                 return "PMB";
695         case CTSVC_VCARD_IMG_DIB:
696                 return "DIB";
697         case CTSVC_VCARD_IMG_PICT:
698                 return "PICT";
699         case CTSVC_VCARD_IMG_PDF:
700                 return "PDF";
701         case CTSVC_VCARD_IMG_PS:
702                 return "PS";
703         case CTSVC_VCARD_IMG_QTIME:
704                 return "QTIME";
705         case CTSVC_VCARD_IMG_MPEG:
706                 return "MPEG";
707         case CTSVC_VCARD_IMG_MPEG2:
708                 return "MPEG2";
709         case CTSVC_VCARD_IMG_AVI:
710                 return "AVI";
711                 /* LCOV_EXCL_STOP */
712         case CTSVC_VCARD_IMG_JPEG:
713         default:
714                 return "JPEG";
715         }
716 }
717
718 static inline int __ctsvc_vcard_put_company_logo(const char *path, char **buf, int *buf_size, int len)
719 {
720         int ret, fd, type;
721         gsize read_len;
722         char *suffix;
723         gchar *buf_image;
724         guchar image[CTSVC_VCARD_PHOTO_MAX_SIZE] = {0};
725
726         suffix = strrchr(path, '.');
727         type = __ctsvc_vcard_get_image_type((const char *)suffix);
728
729         fd = open(path, O_RDONLY);
730         RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : Open Fail(%d)", errno); /* LCOV_EXCL_LINE */
731
732         read_len = 0;
733         while ((ret = read(fd, image+read_len, sizeof(image)-read_len))) {
734                 if (-1 == ret) {
735                         if (EINTR == errno)
736                                 continue; /* LCOV_EXCL_LINE */
737                         else
738                                 break;
739                 }
740                 read_len += ret;
741         }
742         close(fd);
743         RETVM_IF(ret < 0, CONTACTS_ERROR_SYSTEM, "System : read() Fail(%d)", errno); /* LCOV_EXCL_LINE */
744
745         buf_image = g_base64_encode(image, read_len);
746         if (buf_image) {
747                 do {
748                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_LOGO], false)) < 0)
749                                 break;
750                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ";ENCODING=BASE64;TYPE=", false)) < 0)
751                                 break;
752                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, __ctsvc_get_image_type_str(type), false)) < 0)
753                                 break;
754                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ":", false)) < 0)
755                                 break;
756                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, buf_image, false)) < 0)
757                                 break;
758                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
759                                 break;
760                         if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
761                                 break;
762                 } while (0);
763
764                 g_free(buf_image);
765                 if (len < 0) {
766                         /* LCOV_EXCL_START */
767                         ERR("__ctsvc_vcard_append_str() Fail");
768                         return CONTACTS_ERROR_OUT_OF_MEMORY;
769                         /* LCOV_EXCL_STOP */
770                 }
771         }
772         return len;
773 }
774                 /* LCOV_EXCL_START */
775 static bool __ctsvc_vcard_is_valid_custom_label(char *label)
776 {
777         char *src = label;
778         RETV_IF(NULL == label || '\0' == *label, false);
779
780         while (*src) {
781                 char c = src[0];
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 == '-') {
785                         src++;
786                         continue;
787                 }
788                 return false;
789         }
790         return true;
791 }
792                 /* LCOV_EXCL_STOP */
793 static inline int __ctsvc_vcard_put_company_type(int type, char *label, char **buf, int *buf_size, int len)
794 {
795         if (type == CONTACTS_COMPANY_TYPE_WORK) {
796                 /* LCOV_EXCL_START */
797                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=WORK");
798                 /* LCOV_EXCL_STOP */
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);
804                 }
805                 /* LCOV_EXCL_STOP */
806         }
807         return len;
808 }
809
810 static inline int __ctsvc_vcard_append_company(ctsvc_list_s *company_list, char **buf, int *buf_size, int len)
811 {
812         GList *cursor;
813         ctsvc_company_s *company;
814
815         for (cursor = company_list->records; cursor; cursor = cursor->next) {
816
817                 company = cursor->data;
818
819                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ORG]);
820
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 */
823
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);
830                 }
831
832                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
833
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);
837                 }
838
839                 if (company->role) {
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);
842                 }
843
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);
847                 }
848
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);
852                 }
853
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);
857                 }
858
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);
862                 }
863
864                 if (company->logo) {
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 */
867                 }
868         }
869
870         return len;
871 }
872
873 static inline int __ctsvc_vcard_append_note(ctsvc_list_s *note_list, char **buf, int *buf_size, int len)
874 {
875         GList *cursor;
876         ctsvc_note_s *note;
877
878         for (cursor = note_list->records; cursor; cursor = cursor->next) {
879                 note = cursor->data;
880                 if (note->note) {
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);
883                 }
884         }
885
886         return len;
887 }
888
889 static inline int __ctsvc_vcard_2_put_postal_type(int type, char *dest, int dest_size)
890 {
891         int ret_len = 0;
892
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");
905
906         return ret_len;
907 }
908
909 static inline int __ctsvc_vcard_put_postal_type(int type, char *label, char **buf, int *buf_size, int len)
910 {
911         char *type_str = NULL;
912         if (type == CONTACTS_ADDRESS_TYPE_DOM)
913                 type_str = "DOM";
914         else if (type == CONTACTS_ADDRESS_TYPE_INTL)
915                 type_str = "INTL";
916         else if (type == CONTACTS_ADDRESS_TYPE_HOME)
917                 type_str = "HOME";
918                 /* LCOV_EXCL_START */
919         else if (type == CONTACTS_ADDRESS_TYPE_WORK)
920                 type_str = "WORK";
921         else if (type == CONTACTS_ADDRESS_TYPE_POSTAL)
922                 type_str = "POSTAL";
923         else if (type == CONTACTS_ADDRESS_TYPE_PARCEL)
924                 type_str = "PARCEL";
925                 /* LCOV_EXCL_STOP */
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);
931                 }
932                 return len;
933                 /* LCOV_EXCL_STOP */
934         }
935
936         if (type_str) {
937                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
938                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
939         }
940         return len;
941 }
942
943 static inline int __ctsvc_vcard_append_postals(ctsvc_list_s *address_list, char **buf, int *buf_size, int len)
944 {
945         GList *cursor;
946         ctsvc_address_s *address;
947
948         for (cursor = address_list->records; cursor; cursor = cursor->next) {
949                 address = cursor->data;
950                 if (address) {
951                         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ADR]);
952
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 */
955
956                         if (address->is_default)
957                                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
958
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);
974
975                         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
976                 }
977         }
978
979         return len;
980 }
981
982 static inline int __ctsvc_vcard_append_nicknames(ctsvc_list_s *nickname_list, char **buf, int *buf_size, int len)
983 {
984         bool first;
985         GList *cursor;
986         ctsvc_nickname_s *nickname;
987
988         first = true;
989         for (cursor = nickname_list->records; cursor; cursor = cursor->next) {
990                 nickname = cursor->data;
991                 if (nickname->nickname && *nickname->nickname) {
992                         if (first) {
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);
997                                 first = false;
998                         } else {
999                                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ",");
1000                                 CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, nickname->nickname);
1001                         }
1002                 }
1003         }
1004         if (false == first)
1005                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
1006
1007         return len;
1008 }
1009
1010 static inline int __ctsvc_vcard_2_put_number_type(int type, char *dest, int dest_size)
1011 {
1012         int ret_len = 0;
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");
1041
1042         return ret_len;
1043 }
1044
1045 static inline int __ctsvc_vcard_put_number_type(int type, char *label, char **buf, int *buf_size, int len)
1046 {
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);
1086                 }
1087                 return len;
1088         }
1089                 /* LCOV_EXCL_STOP */
1090         return len;
1091 }
1092
1093 static int __ctsvc_vcard_check_utf8(char c)
1094 {
1095         if ((c & 0xff) < (128 & 0xff))
1096                 return 1;
1097                 /* LCOV_EXCL_START */
1098         else if ((c & (char)0xe0) == (char)0xc0)
1099                 return 2;
1100         else if ((c & (char)0xf0) == (char)0xe0)
1101                 return 3;
1102         else if ((c & (char)0xf8) == (char)0xf0)
1103                 return 4;
1104         else if ((c & (char)0xfc) == (char)0xf8)
1105                 return 5;
1106         else if ((c & (char)0xfe) == (char)0xfc)
1107                 return 6;
1108                 /* LCOV_EXCL_STOP */
1109         else
1110                 return CONTACTS_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_LINE */
1111 }
1112
1113 static void __ctsvc_vcard_get_clean_number_for_export(char *str, char *dest)
1114 {
1115         int char_len = 0;
1116         char *s = SAFE_STR(str);
1117         char *r = NULL;
1118
1119         r = dest;
1120
1121         while (*s) {
1122                 char_len = __ctsvc_vcard_check_utf8(*s);
1123                 /* LCOV_EXCL_START */
1124                 if (3 == char_len) {
1125                         if (*s == 0xef) {
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);
1130                                                 r++;
1131                                                 s += 3;
1132                                         } else if (0x8b == *(s+2)) {
1133                                                 /* ef bc 8b : '+' */
1134                                                 *r = '+';
1135                                                 r++;
1136                                                 s += 3;
1137                                         } else if (0x8a == *(s+2)) {
1138                                                 /* ef bc 8a : '*' */
1139                                                 *r = '*';
1140                                                 r++;
1141                                                 s += 3;
1142                                         } else if (0x83 == *(s+2)) {
1143                                                 /* ef bc 83 : '#' */
1144                                                 *r = '#';
1145                                                 r++;
1146                                                 s += 3;
1147                                         } else if (0x8c == *(s+2)) {
1148                                                 /* ef bc 8c : ',' */
1149                                                 *r = 'p';
1150                                                 r++;
1151                                                 s += 3;
1152                                         } else if (0x9b == *(s+2)) {
1153                                                 /* ef bc 9b : ';' */
1154                                                 *r = 'w';
1155                                                 r++;
1156                                                 s += 3;
1157                                         } else {
1158                                                 s += char_len;
1159                                         }
1160                                 } else {
1161                                         s += char_len;
1162                                 }
1163                         } else {
1164                                 s += char_len;
1165                         }
1166                 /* LCOV_EXCL_STOP */
1167                 } else if (1 == char_len) {
1168                         switch (*s) {
1169                         case '/':
1170                         case '.':
1171                         case '0' ... '9':
1172                         case '#':
1173                         case '*':
1174                         case '(':
1175                         case ')':
1176                         case '+':
1177                                 *r = *s;
1178                                 r++;
1179                                 s++;
1180                                 break;
1181                 /* LCOV_EXCL_START */
1182                         case ',':
1183                 /* LCOV_EXCL_STOP */
1184                         case 'p':
1185                 /* LCOV_EXCL_START */
1186                         case 'P':
1187                                 *r = 'p';
1188                                 r++;
1189                                 s++;
1190                                 break;
1191                         case ';':
1192                 /* LCOV_EXCL_STOP */
1193                         case 'w':
1194                 /* LCOV_EXCL_START */
1195                         case 'W':
1196                                 *r = 'w';
1197                                 r++;
1198                                 s++;
1199                                 break;
1200                         case 'a' ... 'o':
1201                 /* LCOV_EXCL_STOP */
1202                         case 'q' ... 'v':
1203                         case 'x' ... 'z':
1204                 /* LCOV_EXCL_START */
1205                                 *r = *s - 0x20;
1206                                 r++;
1207                                 s++;
1208                                 break;
1209                         case 'A' ... 'O':
1210                 /* LCOV_EXCL_STOP */
1211                         case 'Q' ... 'V':
1212                         case 'X' ... 'Z':
1213                 /* LCOV_EXCL_START */
1214                                 *r = *s;
1215                                 r++;
1216                                 s++;
1217                                 break;
1218                 /* LCOV_EXCL_STOP */
1219                         default:
1220                                 s++;
1221                                 break;
1222                         }
1223                 } else {
1224                 /* LCOV_EXCL_START */
1225                         s += char_len;
1226                 /* LCOV_EXCL_STOP */
1227                 }
1228         }
1229         *r = '\0';
1230         return;
1231 }
1232
1233 static inline int __ctsvc_vcard_append_numbers(ctsvc_list_s *number_list, char **buf, int *buf_size, int len)
1234 {
1235         GList *cursor;
1236         ctsvc_number_s *number;
1237
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]);
1244
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 */
1247
1248                         if (number->is_default)
1249                                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
1250
1251                         __ctsvc_vcard_get_clean_number_for_export(number->number, clean_number);
1252                         if (*clean_number)
1253                                 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, clean_number);
1254                 }
1255         }
1256         return len;
1257 }
1258
1259 static inline int __ctsvc_vcard_2_put_email_type(int type, char *dest, int dest_size)
1260 {
1261         int ret_len = 0;
1262
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");
1267
1268         return ret_len;
1269 }
1270
1271 static inline int __ctsvc_vcard_put_email_type(int type, char *label, char **buf, int *buf_size, int len)
1272 {
1273         char *type_str = NULL;
1274         if (CONTACTS_EMAIL_TYPE_HOME == type) {
1275                 type_str = "HOME";
1276         }
1277                 /* LCOV_EXCL_START */
1278         else if (CONTACTS_EMAIL_TYPE_WORK == type) {
1279                 type_str = "WORK";
1280         } else if (CONTACTS_EMAIL_TYPE_MOBILE == type) {
1281                 type_str = "CELL";
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);
1286                 }
1287                 return len;
1288         }
1289                 /* LCOV_EXCL_STOP */
1290         if (type_str) {
1291                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1292                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
1293         }
1294         return len;
1295 }
1296
1297 static inline int __ctsvc_vcard_append_emails(ctsvc_list_s *email_list, char **buf, int *buf_size, int len)
1298 {
1299         GList *cursor;
1300         ctsvc_email_s *email;
1301
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]);
1306
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 */
1309
1310                         if (email->is_default)
1311                                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
1312
1313                         CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, email->email_addr);
1314                 }
1315         }
1316         return len;
1317 }
1318
1319 static inline int __ctsvc_vcard_put_url_type(int type, char *label, char **buf, int *buf_size, int len)
1320 {
1321         char *type_str = NULL;
1322
1323         if (CONTACTS_URL_TYPE_HOME == type) {
1324                 type_str = "HOME";
1325         }
1326                 /* LCOV_EXCL_START */
1327         else if (CONTACTS_URL_TYPE_WORK == type) {
1328                 type_str = "WORK";
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);
1333                 }
1334                 return len;
1335         }
1336                 /* LCOV_EXCL_STOP */
1337         if (type_str) {
1338                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1339                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
1340         }
1341         return len;
1342 }
1343
1344 static inline int __ctsvc_vcard_append_webs(ctsvc_list_s *url_list, char **buf, int *buf_size, int len)
1345 {
1346         GList *cursor;
1347         ctsvc_url_s *url;
1348
1349         for (cursor = url_list->records; cursor; cursor = cursor->next) {
1350                 url = cursor->data;
1351
1352                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_URL]);
1353
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 */
1356
1357                 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, url->url);
1358         }
1359
1360         return len;
1361 }
1362
1363 #define VCARD_INIT_LENGTH 1024
1364 #define VCARD_ITEM_LENGTH 1024
1365
1366 static inline int __ctsvc_vcard_append_events(ctsvc_list_s *event_list, char **buf, int *buf_size, int len)
1367 {
1368         GList *cursor;
1369         ctsvc_event_s *data;
1370         char event[VCARD_ITEM_LENGTH] = {0};
1371
1372         for (cursor = event_list->records; cursor; cursor = cursor->next) {
1373                 data = cursor->data;
1374                 if (0 == data->date) continue;
1375
1376                 event[0] = '\0';
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,
1381                                         CTSVC_CRLF);
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,
1386                                         CTSVC_CRLF);
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,
1393                                                 CTSVC_CRLF);
1394                         } else {
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,
1398                                                 CTSVC_CRLF);
1399                         }
1400                 } else {
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,
1404                                         CTSVC_CRLF);
1405                 }
1406                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, event);
1407         }
1408
1409         return len;
1410 }
1411
1412 static inline int __ctsvc_vcard_append_messengers(ctsvc_list_s *messenger_list, char **buf, int *buf_size, int len)
1413 {
1414         GList *cursor;
1415         ctsvc_messenger_s *messenger;
1416         const char *content_name_messenger = NULL;
1417         const char *content_name_x_type = NULL;
1418
1419         for (cursor = messenger_list->records; cursor; cursor = cursor->next) {
1420                 messenger = cursor->data;
1421
1422                 content_name_messenger = NULL;
1423                 content_name_x_type = NULL;
1424
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];
1429                                 break;
1430                         case CONTACTS_MESSENGER_TYPE_YAHOO:
1431                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_YAHOO];
1432                                 break;
1433                         case CONTACTS_MESSENGER_TYPE_ICQ:
1434                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_ICQ];
1435                                 break;
1436                         case CONTACTS_MESSENGER_TYPE_AIM:
1437                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_AIM];
1438                                 break;
1439                         case CONTACTS_MESSENGER_TYPE_JABBER:
1440                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_JABBER];
1441                                 break;
1442                         case CONTACTS_MESSENGER_TYPE_SKYPE:
1443                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_SKYPE_USERNAME];
1444                                 break;
1445                         case CONTACTS_MESSENGER_TYPE_QQ:
1446                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_QQ];
1447                                 break;
1448                         case CONTACTS_MESSENGER_TYPE_GOOGLE:
1449                                 content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_GOOGLE_TALK];
1450                                 break;
1451                         case CONTACTS_MESSENGER_TYPE_FACEBOOK:
1452                                 content_name_x_type = "FACEBOOK";
1453                                 break;
1454                         case CONTACTS_MESSENGER_TYPE_IRC:
1455                                 content_name_x_type = "IRC";
1456                                 break;
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);
1462                                 }
1463                                 CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
1464                                 break;
1465                         default:
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);
1468                                 break;
1469                         }
1470
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);
1479                         }
1480                 }
1481         }
1482         return len;
1483 }
1484
1485 static inline int __ctsvc_vcard_put_relationship_type(int type, char *label, char **buf, int *buf_size, int len)
1486 {
1487         const char *type_str = NULL;
1488
1489         switch (type) {
1490         case CONTACTS_RELATIONSHIP_TYPE_ASSISTANT:
1491                 type_str = "ASSISTANT";
1492                 break;
1493                 /* LCOV_EXCL_START */
1494         case CONTACTS_RELATIONSHIP_TYPE_BROTHER:
1495                 type_str = "BROTHER";
1496                 break;
1497         case CONTACTS_RELATIONSHIP_TYPE_CHILD:
1498                 type_str = "CHILD";
1499                 break;
1500         case CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER:
1501                 type_str = "DOMESTIC_PARTNER";
1502                 break;
1503         case CONTACTS_RELATIONSHIP_TYPE_FATHER:
1504                 type_str = "FATHER";
1505                 break;
1506         case CONTACTS_RELATIONSHIP_TYPE_FRIEND:
1507                 type_str = "FRIEND";
1508                 break;
1509         case CONTACTS_RELATIONSHIP_TYPE_MANAGER:
1510                 type_str = "MANAGER";
1511                 break;
1512         case CONTACTS_RELATIONSHIP_TYPE_MOTHER:
1513                 type_str = "MOTHER";
1514                 break;
1515         case CONTACTS_RELATIONSHIP_TYPE_PARENT:
1516                 type_str = "PARENT";
1517                 break;
1518         case CONTACTS_RELATIONSHIP_TYPE_PARTNER:
1519                 type_str = "PARTNER";
1520                 break;
1521         case CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY:
1522                 type_str = "REFERRED_BY";
1523                 break;
1524         case CONTACTS_RELATIONSHIP_TYPE_RELATIVE:
1525                 type_str = "RELATIVE";
1526                 break;
1527         case CONTACTS_RELATIONSHIP_TYPE_SISTER:
1528                 type_str = "SISTER";
1529                 break;
1530         case CONTACTS_RELATIONSHIP_TYPE_SPOUSE:
1531                 type_str = "SPOUSE";
1532                 break;
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);
1537                 }
1538                 /* LCOV_EXCL_STOP */
1539                 return len;
1540         }
1541
1542         if (type_str) {
1543                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
1544                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
1545         }
1546
1547         return len;
1548 }
1549
1550 static inline int __ctsvc_vcard_append_relationships(ctsvc_list_s *relationship_list, char **buf, int *buf_size, int len)
1551 {
1552         GList *cursor;
1553         ctsvc_relationship_s *relationship;
1554
1555         for (cursor = relationship_list->records; cursor; cursor = cursor->next) {
1556                 relationship = cursor->data;
1557
1558                 if (relationship->name) {
1559                         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "X-TIZEN-RELATIONSHIP");
1560
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);
1564                 }
1565         }
1566
1567         return len;
1568 }
1569
1570 typedef struct {
1571         const char *src;
1572         unsigned char **image;
1573         unsigned int *image_size;
1574         int ret;
1575 } vcard_image_info;
1576
1577 static bool _ctsvc_vcard_image_util_supported_jpeg_colorspace_cb(
1578                 image_util_colorspace_e colorspace, void *user_data)
1579 {
1580         int width = 0;
1581         int height = 0;
1582         int mimetype = 0;
1583         uint64_t size = 0;
1584         unsigned int size_decode = 0;
1585         void *buffer = NULL;
1586         void *buffer_temp = NULL;
1587         int ret;
1588         vcard_image_info *info = user_data;
1589
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;
1594                 return true;
1595                 /* LCOV_EXCL_STOP */
1596         }
1597
1598         image_util_decode_h dh = NULL;
1599         image_util_image_h decoded_image = NULL;
1600         do {
1601                 unsigned int _width = 0;
1602                 unsigned int _height = 0;
1603                 size_t _size_decode = 0;
1604
1605                 ret = image_util_decode_create(&dh);
1606                 if (IMAGE_UTIL_ERROR_NONE != ret)
1607                         break;
1608                 ret = image_util_decode_set_input_path(dh, info->src);
1609                 if (IMAGE_UTIL_ERROR_NONE != ret)
1610                         break;
1611                 ret = image_util_decode_set_colorspace(dh, colorspace);
1612                 if (IMAGE_UTIL_ERROR_NONE != ret)
1613                         break;
1614                 ret = image_util_decode_run2(dh, &decoded_image);
1615                 if (IMAGE_UTIL_ERROR_NONE != ret)
1616                         break;
1617                 ret = image_util_get_image(decoded_image, &_width, &_height, NULL, (unsigned char**)&buffer, &_size_decode);
1618                 if (IMAGE_UTIL_ERROR_NONE != ret)
1619                         break;
1620
1621                 width = (int)_width;
1622                 height = (int)_height;
1623                 size_decode = (unsigned int)_size_decode;
1624         } while (0);
1625         if (dh)
1626                 ret = image_util_decode_destroy(dh);
1627
1628         if (decoded_image)
1629                 ret = image_util_destroy_image(decoded_image);
1630
1631         if (IMAGE_UTIL_ERROR_NONE != ret || 0 == width || 0 == height) {
1632                 /* LCOV_EXCL_START */
1633                 info->ret = CONTACTS_ERROR_SYSTEM;
1634                 return true;
1635                 /* LCOV_EXCL_STOP */
1636         }
1637         size = (uint64_t)size_decode;
1638
1639         if (limit_size_of_photo < width || limit_size_of_photo < height) { /* need resize */
1640                 /* LCOV_EXCL_START */
1641                 int resized_width;
1642                 int resized_height;
1643                 media_format_h fmt;
1644                 media_packet_h packet;
1645
1646                 /* set resize */
1647                 if (width > height) {
1648                         resized_width = limit_size_of_photo;
1649                         resized_height = height * limit_size_of_photo / width;
1650                 } else {
1651                         resized_height = limit_size_of_photo;
1652                         resized_width = width * limit_size_of_photo / height;
1653                 }
1654
1655                 if (resized_height % 8)
1656                         resized_height -= (resized_height % 8);
1657
1658                 if (resized_width % 8)
1659                         resized_width -= (resized_width % 8);
1660
1661                 fmt = ctsvc_image_util_create_media_format(mimetype, width, height);
1662                 if (NULL == fmt) {
1663                         /* LCOV_EXCL_START */
1664                         ERR("_ctsvc_image_create_media_format() Fail");
1665                         info->ret = CONTACTS_ERROR_SYSTEM;
1666                         free(buffer);
1667                         return false;
1668                         /* LCOV_EXCL_STOP */
1669                 }
1670
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;
1677                         free(buffer);
1678                         return false;
1679                         /* LCOV_EXCL_STOP */
1680                 }
1681
1682                 ret = ctsvc_image_util_resize(packet, resized_width, resized_height, &buffer_temp,
1683                                 &size);
1684
1685                 media_packet_destroy(packet);
1686                 media_format_unref(fmt);
1687
1688                 if (CONTACTS_ERROR_NONE != ret) {
1689                         /* LCOV_EXCL_START */
1690                         free(buffer);
1691                         info->ret = CONTACTS_ERROR_SYSTEM;
1692                         return false;
1693                         /* LCOV_EXCL_STOP */
1694                 }
1695                 free(buffer);
1696                 buffer = buffer_temp;
1697
1698                 width = resized_width;
1699                 height = resized_height;
1700                 /* LCOV_EXCL_STOP */
1701         }
1702
1703         image_util_encode_h eh = NULL;
1704         image_util_image_h image = NULL;
1705         do {
1706                 size_t size_encode = 0;
1707
1708                 ret = image_util_create_image(width, height, colorspace, buffer, size, &image);
1709                 if (IMAGE_UTIL_ERROR_NONE != ret)
1710                         break;
1711
1712                 ret = image_util_encode_create(IMAGE_UTIL_JPEG, &eh);
1713                 if (IMAGE_UTIL_ERROR_NONE != ret)
1714                         break;
1715                 ret = image_util_encode_set_quality(eh, CTSVC_IMAGE_ENCODE_QUALITY);
1716                 if (IMAGE_UTIL_ERROR_NONE != ret)
1717                         break;
1718                 ret = image_util_encode_run_to_buffer(eh, image, info->image, &size_encode);
1719                 if (IMAGE_UTIL_ERROR_NONE != ret)
1720                         break;
1721                 *(info->image_size) = (unsigned int)size_encode;
1722         } while (0);
1723
1724         if (image)
1725                 image_util_destroy_image(image);
1726
1727         if (eh)
1728                 ret = image_util_encode_destroy(eh);
1729         free(buffer);
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;
1734                 return false;
1735                 /* LCOV_EXCL_STOP */
1736         }
1737
1738         info->ret = CONTACTS_ERROR_NONE;
1739         return false;
1740 }
1741
1742 static inline int __ctsvc_vcard_encode_photo(const char *src,
1743                 unsigned char **image, unsigned int *image_size)
1744 {
1745         int ret;
1746         vcard_image_info info = {src, image, image_size, CONTACTS_ERROR_SYSTEM};
1747
1748         ret = image_util_foreach_supported_colorspace(IMAGE_UTIL_JPEG,
1749                         _ctsvc_vcard_image_util_supported_jpeg_colorspace_cb, &info);
1750
1751         if (IMAGE_UTIL_ERROR_NONE != ret)
1752                 return CONTACTS_ERROR_SYSTEM;
1753
1754         return info.ret;
1755 }
1756
1757 static inline int __ctsvc_vcard_put_photo(ctsvc_list_s *image_list, char **buf, int *buf_size, int len)
1758 {
1759         int ret = CONTACTS_ERROR_NONE, fd, type;
1760         unsigned int read_len;
1761         char *suffix;
1762         gchar *buf_image;
1763         unsigned char *image = NULL;
1764         unsigned int img_buf_size = 0;
1765         GList *cursor;
1766         ctsvc_image_s *data;
1767
1768         for (cursor = image_list->records; cursor; cursor = cursor->next) {
1769                 data = cursor->data;
1770                 if (NULL == data->path) continue;
1771
1772                 ret = __ctsvc_vcard_encode_photo(data->path, &image, &read_len);
1773
1774                 if (CONTACTS_ERROR_NONE != ret) {
1775                         INFO("__ctsvc_vcard_encode_photo() Fail(%d)", ret);
1776
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 */
1784                         }
1785
1786                         fd = open(data->path, O_RDONLY);
1787                         if (fd < 0) {
1788                                 /* LCOV_EXCL_START */
1789                                 ERR("System : Open Fail(%d)", errno);
1790                                 free(image);
1791                                 return CONTACTS_ERROR_SYSTEM;
1792                                 /* LCOV_EXCL_STOP */
1793                         }
1794
1795                         read_len = 0;
1796                         while ((ret = read(fd, image+read_len, img_buf_size-read_len))) {
1797                                 if (-1 == ret) {
1798                                         if (EINTR == errno)
1799                                                 continue;
1800                                         else
1801                                                 break;
1802                                 }
1803                                 read_len += ret;
1804                         }
1805                         close(fd);
1806                         if (ret < 0) {
1807                                 /* LCOV_EXCL_START */
1808                                 ERR("System : read() Fail(%d)", errno);
1809                                 free(image);
1810                                 return CONTACTS_ERROR_SYSTEM;
1811                                 /* LCOV_EXCL_STOP */
1812                         }
1813                 }
1814
1815                 suffix = strrchr(data->path, '.');
1816                 type = __ctsvc_vcard_get_image_type((const char *)suffix);
1817
1818                 buf_image = g_base64_encode(image, read_len);
1819                 free(image);
1820
1821                 if (buf_image) {
1822                         do {
1823                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHOTO], false)) < 0)
1824                                         break;
1825                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ";ENCODING=BASE64;TYPE=", false)) < 0)
1826                                         break;
1827                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, __ctsvc_get_image_type_str(type), false)) < 0)
1828                                         break;
1829                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, ":", false)) < 0)
1830                                         break;
1831                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, buf_image, false)) < 0)
1832                                         break;
1833                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
1834                                         break;
1835                                 if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, CTSVC_CRLF, false)) < 0)
1836                                         break;
1837                         } while (0);
1838
1839                         g_free(buf_image);
1840                         if (len < 0) {
1841                                 /* LCOV_EXCL_START */
1842                                 ERR("__ctsvc_vcard_append_str() Fail");
1843                                 return CONTACTS_ERROR_OUT_OF_MEMORY;
1844                                 /* LCOV_EXCL_STOP */
1845                         }
1846                 }
1847         }
1848
1849         return len;
1850 }
1851
1852 static inline int __ctsvc_vcard_append_contact(ctsvc_contact_s *contact, char **buf, int *buf_size, int len)
1853 {
1854         if (contact->name) {
1855                 len = __ctsvc_vcard_append_name(contact->name, buf, buf_size, len);
1856                 RETV_IF(len < 0, len);
1857         }
1858         if (contact->company) {
1859                 len = __ctsvc_vcard_append_company(contact->company, buf, buf_size, len);
1860                 RETV_IF(len < 0, len);
1861         }
1862         if (contact->note) {
1863                 len = __ctsvc_vcard_append_note(contact->note, buf, buf_size, len);
1864                 RETV_IF(len < 0, len);
1865         }
1866         if (contact->postal_addrs) {
1867                 len = __ctsvc_vcard_append_postals(contact->postal_addrs, buf, buf_size, len);
1868                 RETV_IF(len < 0, len);
1869         }
1870         if (contact->numbers) {
1871                 len = __ctsvc_vcard_append_numbers(contact->numbers, buf, buf_size, len);
1872                 RETV_IF(len < 0, len);
1873         }
1874         if (contact->emails) {
1875                 len = __ctsvc_vcard_append_emails(contact->emails, buf, buf_size, len);
1876                 RETV_IF(len < 0, len);
1877         }
1878         if (contact->nicknames) {
1879                 len = __ctsvc_vcard_append_nicknames(contact->nicknames, buf, buf_size, len);
1880                 RETV_IF(len < 0, len);
1881         }
1882         if (contact->urls) {
1883                 len = __ctsvc_vcard_append_webs(contact->urls, buf, buf_size, len);
1884                 RETV_IF(len < 0, len);
1885         }
1886         if (contact->events) {
1887                 len = __ctsvc_vcard_append_events(contact->events, buf, buf_size, len);
1888                 RETV_IF(len < 0, len);
1889         }
1890         if (contact->images) {
1891                 len = __ctsvc_vcard_put_photo(contact->images, buf, buf_size, len);
1892                 RETV_IF(len < 0, len);
1893         }
1894         if (contact->messengers) {
1895                 len = __ctsvc_vcard_append_messengers(contact->messengers, buf, buf_size, len);
1896                 RETV_IF(len < 0, len);
1897         }
1898         if (contact->relationships) {
1899                 len = __ctsvc_vcard_append_relationships(contact->relationships, buf, buf_size, len);
1900                 RETV_IF(len < 0, len);
1901         }
1902
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);
1906         }
1907
1908         if (contact->changed_time) {
1909                 struct tm ts;
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,
1916                                 CTSVC_CRLF);
1917
1918                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
1919         }
1920 #if 0
1921         ctsvc_list_s *profile;
1922 #endif
1923         return len;
1924 }
1925
1926 static inline int __ctsvc_vcard_append_my_profile(ctsvc_my_profile_s *my_profile, char **buf, int *buf_size, int len)
1927 {
1928         if (my_profile->name) {
1929                 len = __ctsvc_vcard_append_name(my_profile->name, buf, buf_size, len);
1930                 RETV_IF(len < 0, len);
1931         }
1932         if (my_profile->company) {
1933                 len = __ctsvc_vcard_append_company(my_profile->company, buf, buf_size, len);
1934                 RETV_IF(len < 0, len);
1935         }
1936         if (my_profile->note) {
1937                 len = __ctsvc_vcard_append_note(my_profile->note, buf, buf_size, len);
1938                 RETV_IF(len < 0, len);
1939         }
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);
1943         }
1944         if (my_profile->numbers) {
1945                 len = __ctsvc_vcard_append_numbers(my_profile->numbers, buf, buf_size, len);
1946                 RETV_IF(len < 0, len);
1947         }
1948         if (my_profile->emails) {
1949                 len = __ctsvc_vcard_append_emails(my_profile->emails, buf, buf_size, len);
1950                 RETV_IF(len < 0, len);
1951         }
1952         if (my_profile->nicknames) {
1953                 len = __ctsvc_vcard_append_nicknames(my_profile->nicknames, buf, buf_size, len);
1954                 RETV_IF(len < 0, len);
1955         }
1956         if (my_profile->urls) {
1957                 len = __ctsvc_vcard_append_webs(my_profile->urls, buf, buf_size, len);
1958                 RETV_IF(len < 0, len);
1959         }
1960         if (my_profile->events) {
1961                 len = __ctsvc_vcard_append_events(my_profile->events, buf, buf_size, len);
1962                 RETV_IF(len < 0, len);
1963         }
1964         if (my_profile->images) {
1965                 len = __ctsvc_vcard_put_photo(my_profile->images, buf, buf_size, len);
1966                 RETV_IF(len < 0, len);
1967         }
1968         if (my_profile->messengers) {
1969                 len = __ctsvc_vcard_append_messengers(my_profile->messengers, buf, buf_size, len);
1970                 RETV_IF(len < 0, len);
1971         }
1972         if (my_profile->relationships) {
1973                 len = __ctsvc_vcard_append_relationships(my_profile->relationships, buf, buf_size, len);
1974                 RETV_IF(len < 0, len);
1975         }
1976
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);
1980         }
1981
1982         if (my_profile->changed_time) {
1983                 /* LCOV_EXCL_START */
1984                 struct tm ts;
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,
1991                                 CTSVC_CRLF);
1992
1993                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
1994                 /* LCOV_EXCL_STOP */
1995         }
1996
1997 #if 0
1998         ctsvc_list_s *profile;
1999 #endif
2000         return len;
2001 }
2002
2003 static inline int __ctsvc_vcard_append_start_vcard_3_0(char **buf, int *buf_size, int len)
2004 {
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);
2009         return len;
2010 }
2011
2012 static inline int __ctsvc_vcard_append_end_vcard(char **buf, int *buf_size, int len)
2013 {
2014         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "END:VCARD");
2015         CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
2016         return len;
2017 }
2018
2019 static int __ctsvc_vcard_make(ctsvc_contact_s *contact, char **vcard_stream)
2020 {
2021         char *buf = NULL;
2022         int buf_size = VCARD_INIT_LENGTH;
2023         int len = 0;
2024
2025         __ctsvc_vcard_initial();
2026
2027         buf = calloc(1, buf_size);
2028         if (NULL == buf) {
2029                 /* LCOV_EXCL_START */
2030                 ERR("calloc() Fail");
2031                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2032                 /* LCOV_EXCL_STOP */
2033         }
2034
2035         len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
2036         if (len < 0) {
2037                 /* LCOV_EXCL_START */
2038                 free(buf);
2039                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2040                 /* LCOV_EXCL_STOP */
2041         }
2042
2043         len = __ctsvc_vcard_append_contact(contact, &buf, &buf_size, len);
2044         if (len < 0) {
2045                 /* LCOV_EXCL_START */
2046                 free(buf);
2047                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2048                 /* LCOV_EXCL_STOP */
2049         }
2050
2051         len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
2052         if (len < 0) {
2053                 /* LCOV_EXCL_START */
2054                 free(buf);
2055                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2056                 /* LCOV_EXCL_STOP */
2057         }
2058
2059         len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
2060         if (len < 0) {
2061                 /* LCOV_EXCL_START */
2062                 free(buf);
2063                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2064                 /* LCOV_EXCL_STOP */
2065         }
2066         *vcard_stream = buf;
2067
2068         return CONTACTS_ERROR_NONE;
2069 }
2070
2071 static int __ctsvc_vcard_make_from_my_profile(ctsvc_my_profile_s *my_profile, char **vcard_stream)
2072 {
2073         char *buf = NULL;
2074         int buf_size = VCARD_INIT_LENGTH;
2075         int len = 0;
2076
2077         __ctsvc_vcard_initial();
2078
2079         buf = calloc(1, buf_size);
2080         if (NULL == buf) {
2081                 /* LCOV_EXCL_START */
2082                 ERR("calloc() Fail");
2083                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2084                 /* LCOV_EXCL_STOP */
2085         }
2086
2087         len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
2088         if (len < 0) {
2089                 /* LCOV_EXCL_START */
2090                 free(buf);
2091                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2092                 /* LCOV_EXCL_STOP */
2093         }
2094
2095         len = __ctsvc_vcard_append_my_profile(my_profile, &buf, &buf_size, len);
2096         if (len < 0) {
2097                 /* LCOV_EXCL_START */
2098                 free(buf);
2099                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2100                 /* LCOV_EXCL_STOP */
2101         }
2102
2103         len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
2104         if (len < 0) {
2105                 /* LCOV_EXCL_START */
2106                 free(buf);
2107                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2108                 /* LCOV_EXCL_STOP */
2109         }
2110
2111         len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
2112         if (len < 0) {
2113                 /* LCOV_EXCL_START */
2114                 free(buf);
2115                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2116                 /* LCOV_EXCL_STOP */
2117         }
2118
2119         *vcard_stream = buf;
2120
2121         return CONTACTS_ERROR_NONE;
2122 }
2123
2124 EXPORT_API int contacts_vcard_make_from_contact(contacts_record_h record, char **vcard_stream)
2125 {
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;
2130
2131         RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER,
2132                         "contact(%p), vcard_stream(%p)", record, vcard_stream);
2133
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);
2137
2138         return __ctsvc_vcard_make(contact, vcard_stream);
2139 }
2140
2141 EXPORT_API int contacts_vcard_make_from_my_profile(contacts_record_h record, char **vcard_stream)
2142 {
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;
2147
2148         RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER,
2149                         "my_profile(%p), vcard_stream(%p)", record, vcard_stream);
2150
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);
2154
2155         return __ctsvc_vcard_make_from_my_profile(my_profile, vcard_stream);
2156 }
2157
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)
2160 {
2161         time_t changed_time = 0;
2162         ctsvc_contact_s *contact;
2163         GList *cursor = NULL;
2164
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);
2170                 }
2171         }
2172
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);
2178                 }
2179         }
2180
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);
2186                 }
2187         }
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);
2193                 }
2194         }
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);
2200                 }
2201         }
2202
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);
2208                 }
2209         }
2210
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);
2216                 }
2217         }
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);
2223                 }
2224         }
2225
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);
2231                 }
2232         }
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);
2238                 }
2239         }
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);
2245                 }
2246         }
2247
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);
2253                 }
2254         }
2255
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);
2261                 }
2262         }
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;
2267         }
2268
2269         if (changed_time) {
2270                 struct tm ts;
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,
2277                                 CTSVC_CRLF);
2278
2279                 CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
2280         }
2281
2282 #if 0
2283         ctsvc_list_s *profile;
2284 #endif
2285         return len;
2286 }
2287 #endif /* _CONTACTS_IPC_CLIENT */
2288
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)
2292 {
2293         char *buf = NULL;
2294         int buf_size = VCARD_INIT_LENGTH;
2295         int len = 0;
2296
2297         RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
2298         *vcard_stream = NULL;
2299
2300         __ctsvc_vcard_initial();
2301
2302         buf = calloc(1, buf_size);
2303         if (NULL == buf) {
2304                 /* LCOV_EXCL_START */
2305                 ERR("calloc() Fail");
2306                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2307                 /* LCOV_EXCL_STOP */
2308         }
2309
2310         len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
2311         if (len < 0) {
2312                 /* LCOV_EXCL_START */
2313                 free(buf);
2314                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2315                 /* LCOV_EXCL_STOP */
2316         }
2317
2318         len = __ctsvc_vcard_append_person(person, list_contacts, &buf, &buf_size, len);
2319         if (len < 0) {
2320                 /* LCOV_EXCL_START */
2321                 free(buf);
2322                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2323                 /* LCOV_EXCL_STOP */
2324         }
2325         len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
2326         if (len < 0) {
2327                 /* LCOV_EXCL_START */
2328                 free(buf);
2329                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2330                 /* LCOV_EXCL_STOP */
2331         }
2332
2333         len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
2334         if (len < 0) {
2335                 /* LCOV_EXCL_START */
2336                 free(buf);
2337                 return CONTACTS_ERROR_OUT_OF_MEMORY;
2338                 /* LCOV_EXCL_STOP */
2339         }
2340
2341         *vcard_stream = buf;
2342
2343         return CONTACTS_ERROR_NONE;
2344 }
2345 #endif /* _CONTACTS_IPC_CLIENT */
2346
2347 #ifdef _CONTACTS_IPC_CLIENT
2348 EXPORT_API int contacts_vcard_make_from_person(contacts_record_h record, char **vcard_stream)
2349 {
2350         CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
2351         int ret;
2352         ctsvc_person_s *person;
2353         contacts_query_h query = NULL;
2354         contacts_filter_h filter = NULL;
2355         contacts_list_h list = NULL;
2356
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;
2360
2361         person = (ctsvc_person_s*)record;
2362
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);
2365
2366         do {
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;
2373         } while (0);
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);
2378         return ret;
2379 }
2380 #endif
2381
2382 static inline char* __ctsvc_vcard_remove_empty_line(char *src)
2383 {
2384         while (*src) {
2385                 if ('\n' != *src && '\r' != *src)
2386                         break;
2387                 src++;
2388         }
2389         return src;
2390 }
2391
2392 static char* __ctsvc_vcard_check_word(char *src, const char *word)
2393 {
2394         bool start = false;
2395
2396         RETV_IF(NULL == src, NULL);
2397
2398         src = __ctsvc_vcard_remove_empty_line(src);
2399
2400         while (*src) {
2401                 switch (*src) {
2402                 case ' ':
2403                 case ':':
2404                 case ';':
2405                         src++;
2406                         break;
2407                 default:
2408                         start = true;
2409                         break;
2410                 }
2411                 if (start) break;
2412         }
2413
2414         while (*src == *word) {
2415                 src++;
2416                 word++;
2417
2418                 if ('\0' == *src || '\0' == *word)
2419                         break;
2420         }
2421
2422         if ('\0' == *word)
2423                 return src;
2424         else
2425                 return NULL;
2426 }
2427
2428 static int __ctsvc_vcard_check_content_type(char **vcard)
2429 {
2430         int i;
2431         char *new_start;
2432
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))
2436                         break;
2437         }
2438
2439         if (CTSVC_VCARD_VALUE_MAX == i) {
2440                 return CTSVC_VCARD_VALUE_NONE;
2441         } else {
2442                 *vcard = new_start;
2443                 return i;
2444         }
2445 }
2446
2447 static bool __ctsvc_vcard_has_unsupported_format(const char *row)
2448 {
2449         RETV_IF(NULL == row, false);
2450
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))
2460                 has_xcustom = true;
2461
2462         if ((quoted1 != NULL && quoted1 < end_of_raw) ||(quoted2 != NULL && quoted2 < end_of_raw))
2463                 has_quoted = true;
2464
2465         /* quoted-printable is not supported in custom type */
2466         if (has_xcustom && has_quoted) {
2467                 INFO("This row has unsupported format");
2468                 return true;
2469         }
2470                 /* LCOV_EXCL_STOP */
2471         return false;
2472 }
2473                 /* LCOV_EXCL_START */
2474 static inline char* __ctsvc_vcard_pass_unsupported(char *vcard)
2475 {
2476         while (*vcard) {
2477                 if ('\n' == *vcard)
2478                         return (vcard + 1);
2479                 vcard++;
2480         }
2481
2482         return NULL;
2483 }
2484                 /* LCOV_EXCL_STOP */
2485 static char* __ctsvc_strtok(char *val, char c)
2486 {
2487         char *before = NULL;
2488         while (*val) {
2489                 if (*val == c && (NULL == before || *before != '\\')) {
2490                         *val = '\0';
2491                         return (val+1);
2492                 }
2493                 before = val;
2494                 val++;
2495         }
2496         return val;
2497 }
2498
2499 static inline bool __ctsvc_vcard_check_base64_encoded(char *src)
2500 {
2501         int ret;
2502         char *tmp = src;
2503
2504         while (*tmp) {
2505                 if ('B' == *tmp) {
2506                 /* LCOV_EXCL_START */
2507                         ret = strncmp(tmp, "BASE64", sizeof("BASE64") - 1);
2508                         if (STRING_EQUAL == ret)
2509                                 return true;
2510                 /* LCOV_EXCL_STOP */
2511                 } else if (':' == *tmp || '\r' == *tmp) {
2512                         break;
2513                 }
2514                 tmp++;
2515         }
2516         return false;
2517 }
2518
2519 static inline int __ctsvc_vcard_check_quoted(char *src, int max, int *quoted)
2520 {
2521         int ret;
2522         if (TRUE == *quoted)
2523                 return TRUE;
2524
2525         while (*src && max) {
2526                 if ('Q' == *src) {
2527                 /* LCOV_EXCL_START */
2528                         ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
2529                         if (STRING_EQUAL == ret) {
2530                                 *quoted = TRUE;
2531                                 return TRUE;
2532                         }
2533                 /* LCOV_EXCL_STOP */
2534                 } else if (':' == *src) {
2535                         break;
2536                 }
2537                 src++;
2538                 max--;
2539         }
2540         return FALSE;
2541 }
2542
2543 static inline int __ctsvc_vcard_remove_folding(char *folded_src)
2544 {
2545         char *result = folded_src;
2546
2547         RETV_IF(NULL == folded_src, CONTACTS_ERROR_INVALID_PARAMETER);
2548
2549         while (*folded_src) {
2550                 if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
2551                         folded_src += 3;
2552                 else if ('\n' == *folded_src && ' ' == *(folded_src+1))
2553                         folded_src += 2;
2554
2555                 if ('\0' == *folded_src)
2556                         break;
2557
2558                 *result = *folded_src;
2559                 result++;
2560                 folded_src++;
2561         }
2562         *result = '\0';
2563         return CONTACTS_ERROR_NONE;
2564 }
2565                 /* LCOV_EXCL_START */
2566 static inline int __ctsvc_vcard_hex_to_dec(char hex)
2567 {
2568         switch (hex) {
2569         case '0' ... '9':
2570                 return hex - '0';
2571         case 'a' ... 'f':
2572                 return hex - 'a' + 10;
2573         case 'A' ... 'F':
2574                 return hex - 'A' + 10;
2575         default:
2576                 return -1;
2577         }
2578 }
2579 static inline int __ctsvc_vcard_decode_quoted_val(char *val)
2580 {
2581         char *src, *dest;
2582         int pre;
2583
2584         src = strchr(val, ':');
2585         if (NULL == src)
2586                 src = val;
2587
2588         dest = src;
2589         while (*src) {
2590                 if ('=' == *src) {
2591                         pre = __ctsvc_vcard_hex_to_dec(*(src+1));
2592                         if (0 <= pre) {
2593                                 *dest = (char)((pre << 4) + __ctsvc_vcard_hex_to_dec(*(src+2)));
2594                                 dest++;
2595                                 src += 2;
2596                         } else {
2597                                 if ('\r' == *(src+1) && '\n' == *(src+2))
2598                                         src += 2;
2599                         }
2600                 } else {
2601                         *dest = *src;
2602                         dest++;
2603                 }
2604                 src++;
2605         }
2606
2607         *dest = '\0';
2608         return dest - val;
2609 }
2610                 /* LCOV_EXCL_STOP */
2611 static inline char* __ctsvc_vcard_translate_charset(char *src, int len)
2612 {
2613         int ret;
2614         char *val = src;
2615
2616         while (*val) {
2617                 if ('C' == *val) {
2618                         ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
2619                         if (STRING_EQUAL == ret) {
2620                                 val += sizeof("CHARSET");
2621                                 break;
2622                         }
2623                 } else if (':' == *val) {
2624                         return NULL;
2625                 }
2626                 val++;
2627         }
2628
2629         if (*val) {
2630                 UChar *temp;
2631                 UConverter *conv;
2632                 UErrorCode err = U_ZERO_ERROR;
2633                 int dest_size = 0;
2634                 int temp_size = 0;
2635                 int src_len, i = 0;
2636                 char enc[32] = {0}, *dest;
2637
2638                 while (';' != *val && ':' != *val)
2639                         enc[i++] = *val++;
2640
2641                 enc[i] = '\0';
2642                 if (0 == strcasecmp("UTF-8", enc))
2643                         return NULL;
2644                         /* LCOV_EXCL_START */
2645                 while (':' != *val)
2646                         val++;
2647
2648                 src_len = len - (val - src);
2649
2650                 temp_size = (src_len+1) * sizeof(UChar);
2651                 temp = malloc(temp_size);
2652                 if (NULL == temp) {
2653                         ERR("malloc() Fail");
2654                         return NULL;
2655                         /* LCOV_EXCL_STOP */
2656                 }
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 */
2662                 ucnv_close(conv);
2663
2664                 dest_size = temp_size*2;
2665                 dest = malloc(dest_size);
2666                 if (NULL == dest) {
2667                         ERR("malloc() Fail");
2668                         free(temp);
2669                         return NULL;
2670                         /* LCOV_EXCL_STOP */
2671                 }
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 */
2676                 ucnv_close(conv);
2677                 free(temp);
2678
2679                 return dest;
2680         }
2681         return NULL;
2682 }
2683
2684 static void __ctsvc_vcard_get_prefix(char **prefix, const char *src)
2685 {
2686         char *temp = strchr(src, ':');
2687         if (temp) {
2688                 int len = (int)temp - (int)src;
2689                 *prefix = calloc(len+1, sizeof(char));
2690                 if (*prefix)
2691                         snprintf(*prefix, len+1, "%s", src);
2692         } else {
2693                 *prefix = NULL;
2694         }
2695 }
2696
2697 static char* __ctsvc_vcard_get_val(int ver, char *src, char **prefix, char **dest)
2698 {
2699         int quoted;
2700         bool start = false;
2701         char *cursor;
2702
2703         RETV_IF(NULL == src, NULL);
2704         RETV_IF(NULL == dest, NULL);
2705
2706         while (*src) {
2707                 switch (*src) {
2708                 case '\n':
2709                         return NULL;
2710                 case '\r':
2711                 case ' ':
2712                         src++;
2713                         break;
2714                 default:
2715                         start = true;
2716                         break;
2717                 }
2718                 if (start) break;
2719         }
2720
2721         quoted = FALSE;
2722         cursor = src;
2723         if (CTSVC_VCARD_VER_2_1 == ver) {
2724                 /* LCOV_EXCL_START */
2725                 while (*cursor) {
2726                         if ('=' == *cursor && __ctsvc_vcard_check_quoted(src, cursor - src, &quoted)) {
2727                                 if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
2728                                         cursor += 2;
2729                         } else {
2730                                 if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
2731                                         break;
2732                                 if ('\n' == *cursor && ' ' != *(cursor+1))
2733                                         break;
2734                         }
2735
2736                         cursor++;
2737                 }
2738                 /* LCOV_EXCL_STOP */
2739         } else {
2740                 while (*cursor) {
2741                         if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
2742                                 break;
2743
2744                         if ('\n' == *cursor && ' ' != *(cursor+1))
2745                                 break;
2746
2747                         cursor++;
2748                 }
2749         }
2750
2751         if (src == cursor) {
2752                 /* LCOV_EXCL_START */
2753                 *dest = NULL;
2754                 return NULL;
2755                 /* LCOV_EXCL_STOP */
2756         } else {
2757                 int len = 0;
2758                 char temp = *cursor;
2759                 char *new_dest;
2760
2761                 if (prefix)
2762                         __ctsvc_vcard_get_prefix(prefix, src);
2763
2764                 *cursor = '\0';
2765                 *dest = strdup(src);
2766                 if (NULL == *dest) {
2767                         /* LCOV_EXCL_START */
2768                         ERR("strdup() Fail");
2769                         return NULL;
2770                         /* LCOV_EXCL_STOP */
2771                 }
2772                 if (CTSVC_VCARD_VER_2_1 != ver)
2773                         __ctsvc_vcard_remove_folding(*dest);
2774
2775                 if (__ctsvc_vcard_check_quoted(*dest, -1, &quoted))
2776                         len = __ctsvc_vcard_decode_quoted_val(*dest);
2777                 if (0 == len)
2778                         len = strlen(*dest);
2779                 new_dest = __ctsvc_vcard_translate_charset(*dest, len);
2780                 if (new_dest) {
2781                 /* LCOV_EXCL_START */
2782                         free(*dest);
2783                         *dest = new_dest;
2784                 /* LCOV_EXCL_STOP */
2785                 }
2786                 *cursor = temp;
2787                 return (cursor + 1);
2788         }
2789 }
2790
2791 static inline char* __ctsvc_get_content_value(char *val)
2792 {
2793         char *temp;
2794
2795         temp = strchr(val, ':');
2796         if (temp)
2797                 temp++;
2798         else
2799                 temp = val;
2800
2801         RETVM_IF('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
2802                         NULL, "Invalid vcard content");
2803
2804         return temp;
2805 }
2806
2807 static char* __ctsvc_vcard_remove_escape_char(char *str)
2808 {
2809         char *s = SAFE_STR(str);
2810         char *r = s;
2811         while (*s) {
2812                 if (*s == '\\' && *(s+1)) {
2813                         char *n = (char*)(s+1);
2814                         switch (*n) {
2815                 /* LCOV_EXCL_START */
2816                         case 'n':
2817                         case 'N':
2818                                 *r = '\n';
2819                                 s++;
2820                                 break;
2821                 /* LCOV_EXCL_STOP */
2822                         case ';':
2823                         case ':':
2824                         case ',':
2825                         case '<':
2826                         case '>':
2827                         case '\\':
2828                                 *r = *n;
2829                                 s++;
2830                                 break;
2831                 /* LCOV_EXCL_START */
2832                         case 0xA1:  /* en/em backslash */
2833                                 if (*(n+1) && 0xAC == *(n+1)) {
2834                                         *r = *n;
2835                                         r++;
2836                                         *r = *(n+1);
2837                                         s += 2;
2838                                 }
2839                                 break;
2840                         case 0x81:  /* en/em backslash */
2841                                 if (*(n+1) && 0x5F == *(n+1)) {
2842                                         *r = *n;
2843                                         r++;
2844                                         *r = *(n+1);
2845                                         s += 2;
2846                                 }
2847                                 break;
2848                         default:
2849                                 *r = *s;
2850                                 break;
2851                 /* LCOV_EXCL_STOP */
2852                         }
2853                         r++;
2854                         s++;
2855                 } else {
2856                         *r = *s;
2857                         r++;
2858                         s++;
2859                 }
2860         }
2861         *r = '\0';
2862         return str;
2863 }
2864
2865 static inline int __ctsvc_vcard_get_display_name(ctsvc_list_s *name_list, char *val)
2866 {
2867         int ret;
2868         int count;
2869         char *temp;
2870         char *first_name = NULL;
2871         char *last_name = NULL;
2872         contacts_record_h name;
2873
2874         temp = __ctsvc_get_content_value(val);
2875         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
2876
2877         contacts_list_get_count((contacts_list_h)name_list, &count);
2878         if (count <= 0) {
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);
2882         } else {
2883                 contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
2884         }
2885
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);
2890
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;
2896 }
2897
2898 #define CTS_GET_MULTIPLE_COMPONENT(dest, src, src_temp, separator) \
2899         src_temp = src; \
2900 separator = false; \
2901 while (src_temp && *src_temp) { \
2902         if (*src_temp == ';') { \
2903                 separator = true; \
2904                 *src_temp = '\0'; \
2905                 src = __ctsvc_vcard_remove_escape_char(src); \
2906                 dest = SMART_STRDUP(src); \
2907                 src = src_temp+1; \
2908                 break; \
2909         } \
2910         else if (*src_temp == '\\') {\
2911                 src_temp += 2; \
2912                 continue; \
2913         } \
2914         src_temp++; \
2915 } \
2916 if (false == separator && src && *src) { \
2917         src = __ctsvc_vcard_remove_escape_char(src); \
2918         dest = SMART_STRDUP(src); \
2919         break; \
2920 }
2921
2922 static inline int __ctsvc_vcard_get_name(ctsvc_list_s *name_list, char *val)
2923 {
2924         int ret;
2925         int count;
2926         char *start;
2927         contacts_record_h name;
2928
2929         start = __ctsvc_get_content_value(val);
2930         RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
2931
2932         contacts_list_get_count((contacts_list_h)name_list, &count);
2933         if (count <= 0) {
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);
2937         } else {
2938                 /* LCOV_EXCL_START */
2939                 contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
2940                 /* LCOV_EXCL_STOP */
2941         }
2942
2943         contacts_record_set_str(name, _contacts_name.first, NULL);  /* remove FN */
2944
2945         do {
2946                 bool separator = false;
2947                 char *start_temp;
2948
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);
2954
2955                 ERR("invalid name type");
2956         } while (0);
2957
2958         return CONTACTS_ERROR_NONE;
2959 }
2960
2961 static inline int __ctsvc_vcard_get_phonetic_name(ctsvc_list_s *name_list, int type, char *val)
2962 {
2963         int ret;
2964         int count;
2965         char *start;
2966         const char separator = ';';
2967         contacts_record_h name;
2968
2969         start = __ctsvc_get_content_value(val);
2970         RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
2971
2972         contacts_list_get_count((contacts_list_h)name_list, &count);
2973         if (count <= 0) {
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);
2977         } else {
2978                 contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
2979         }
2980
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));
2988
2989         return CONTACTS_ERROR_NONE;
2990 }
2991
2992 static inline int __ctsvc_vcard_get_nickname(ctsvc_list_s *nickname_list, char *val)
2993 {
2994         int ret = CONTACTS_ERROR_NONE;
2995         char *temp;
2996         char *start;
2997         char *last;
2998         const char *separator = ",";
2999
3000         start = __ctsvc_get_content_value(val);
3001         RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
3002
3003         temp = strtok_r(start, separator, &last);
3004         while (temp) {
3005                 if ('\0' == *temp) continue;
3006
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;
3019                         return ret;
3020                         /* LCOV_EXCL_STOP */
3021                 }
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);
3024
3025                 temp = strtok_r(NULL, separator, &last);
3026         }
3027
3028         return CONTACTS_ERROR_NONE;
3029 }
3030
3031 static inline int __ctsvc_vcard_get_photo(contacts_record_h contact, ctsvc_list_s *image_list, char *prefix, char *val)
3032 {
3033         int ret, type, fd;
3034         gsize size;
3035         guchar *buf;
3036         char *temp;
3037         char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
3038         contacts_record_h image;
3039         struct timeval tv;
3040
3041         temp = strchr(val, ':');
3042         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "val is invalid");
3043
3044         *temp = '\0';
3045
3046         type = __ctsvc_vcard_get_image_type((const char *)prefix);
3047
3048         buf = g_base64_decode(temp+1, &size);
3049         if ((0 == size) || (NULL == buf)) {
3050                 /* LCOV_EXCL_START */
3051                 g_free(buf);
3052                 return CONTACTS_ERROR_NONE;
3053                 /* LCOV_EXCL_STOP */
3054         }
3055
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));
3059
3060         fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
3061         if (fd < 0) {
3062                 /* LCOV_EXCL_START */
3063                 g_free(buf);
3064                 ERR("System : open Fail(%d)", errno);
3065                 return CONTACTS_ERROR_SYSTEM;
3066                 /* LCOV_EXCL_STOP */
3067         }
3068
3069         while (0 < size) {
3070                 ret = write(fd, buf, size);
3071                 if (ret <= 0) {
3072                         /* LCOV_EXCL_START */
3073                         if (EINTR == errno) {
3074                                 continue;
3075                         } else {
3076                                 ERR("write() Fail(%d)", errno);
3077                                 close(fd);
3078                                 g_free(buf);
3079                                 if (ENOSPC == errno)
3080                                         return CONTACTS_ERROR_FILE_NO_SPACE;   /* No space */
3081                                 else
3082                                         return CONTACTS_ERROR_SYSTEM;   /* IO error */
3083                         /* LCOV_EXCL_STOP */
3084                         }
3085                 }
3086                 size -= ret;
3087         }
3088
3089         close(fd);
3090         g_free(buf);
3091
3092         ret = contacts_record_create(_contacts_image._uri, &image);
3093         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3094
3095         contacts_record_set_str(image, _contacts_image.path, dest);
3096         ((ctsvc_image_s*)image)->is_vcard = true;
3097
3098         contacts_list_add((contacts_list_h)image_list, image);
3099
3100         /* _contacts_contact.image_thumbnail_path is a read-only property */
3101         ((ctsvc_contact_s*)contact)->image_thumbnail_path = strdup(dest);
3102
3103         return CONTACTS_ERROR_NONE;
3104
3105 }
3106                         /* LCOV_EXCL_START */
3107 static inline void __ctsvc_vcard_get_event_type(contacts_record_h event, char *val)
3108 {
3109         int type = CONTACTS_EVENT_TYPE_OTHER;
3110         char *temp, *result, *last = NULL;
3111         char *lower, *lower_temp;
3112
3113         temp = strtok_r(val, ";", &last);
3114         while (temp) {
3115                 lower = strdup(temp);
3116                 if (NULL == lower) {
3117                         ERR("strdup() Fail");
3118                         break;
3119                 }
3120                 lower_temp = lower;
3121                 while (*lower_temp) {
3122                         *lower_temp = tolower(*lower_temp);
3123                         lower_temp++;
3124                 }
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);
3130                 }
3131
3132                 free(lower);
3133                 temp = strtok_r(NULL, ";", &last);
3134         }
3135         contacts_record_set_int(event, _contacts_event.type, type);
3136 }
3137                         /* LCOV_EXCL_STOP */
3138
3139 static inline int __ctsvc_vcard_get_event(ctsvc_list_s *event_list, int type, char *prefix, char *val)
3140 {
3141         int ret;
3142         contacts_record_h event;
3143         char *dest, *src, *date;
3144
3145         date = __ctsvc_get_content_value(val);
3146         if (NULL == date) {
3147                 /* LCOV_EXCL_START */
3148                 ERR("vcard");
3149                 return CONTACTS_ERROR_INVALID_PARAMETER;
3150                 /* LCOV_EXCL_STOP */
3151         }
3152
3153         dest = src = date;
3154         while (*src) {
3155                 if ('0' <= *src && *src <= '9') {
3156                         *dest = *src;
3157                         dest++;
3158                 }
3159                 src++;
3160                 if (8 <= dest - date)
3161                         break;
3162         }
3163         *dest = '\0';
3164         if ('\0' == *date) {
3165                 /* LCOV_EXCL_START */
3166                 ERR("date(%s)", date);
3167                 return CONTACTS_ERROR_INVALID_PARAMETER;
3168                 /* LCOV_EXCL_STOP */
3169         }
3170
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);
3175                 return ret;
3176                 /* LCOV_EXCL_STOP */
3177         }
3178
3179         contacts_record_set_int(event, _contacts_event.date, atoi(date));
3180
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 */
3189
3190         contacts_list_add((contacts_list_h)event_list, event);
3191         return CONTACTS_ERROR_NONE;
3192 }
3193
3194
3195 static inline void __ctsvc_vcard_get_company_type(contacts_record_h company, char *val)
3196 {
3197         char *temp, *result, *last = NULL;
3198         char *lower, *lower_temp;
3199         int type = CONTACTS_COMPANY_TYPE_OTHER;
3200
3201         temp = strtok_r(val, ";", &last);
3202         while (temp) {
3203                 lower = strdup(temp);
3204                 if (NULL == lower) {
3205                         ERR("strdup() Fail");
3206                         break;
3207                 }
3208                 lower_temp = lower;
3209                 while (*lower_temp) {
3210                         *lower_temp = tolower(*lower_temp);
3211                         lower_temp++;
3212                 }
3213
3214                 result = strstr(lower, "work");
3215                 if (result)
3216                         /* LCOV_EXCL_START */
3217                         type = CONTACTS_COMPANY_TYPE_WORK;
3218                         /* LCOV_EXCL_STOP */
3219
3220                 result = strstr(lower, "x-");
3221                 if (result) {
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 */
3226                 }
3227
3228                 free(lower);
3229                 temp = strtok_r(NULL, ";", &last);
3230         }
3231         contacts_record_set_int(company, _contacts_company.type, type);
3232 }
3233
3234 static contacts_record_h __ctsvc_vcard_get_company_empty_record(ctsvc_list_s *company_list, int property_id)
3235 {
3236         contacts_record_h record_temp = NULL;
3237         contacts_record_h record = NULL;
3238         contacts_list_h list = (contacts_list_h)company_list;
3239
3240         contacts_list_last(list);
3241         while (CONTACTS_ERROR_NONE == contacts_list_get_current_record_p(list, &record_temp)) {
3242                 char *value = NULL;
3243                 contacts_record_get_str_p(record_temp, property_id, &value);
3244                 if (NULL == value) {
3245                         record = record_temp;
3246                         break;
3247                 }
3248                 contacts_list_prev(list);
3249         }
3250
3251         return record;
3252 }
3253
3254 static inline int __ctsvc_vcard_get_company_value(ctsvc_list_s *company_list, int property_id, char *val)
3255 {
3256         char *value;
3257         contacts_record_h company;
3258
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);
3264         }
3265
3266         value = __ctsvc_get_content_value(val);
3267         RETV_IF(NULL == value, CONTACTS_ERROR_NO_DATA);
3268
3269         contacts_record_set_str(company, property_id, __ctsvc_vcard_remove_escape_char(value));
3270
3271         return CONTACTS_ERROR_NONE;
3272 }
3273
3274 static inline int __ctsvc_vcard_get_company(ctsvc_list_s *company_list, char *prefix, char *val)
3275 {
3276         char *start, *depart;
3277         const char separator = ';';
3278         contacts_record_h company;
3279
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);
3285         }
3286
3287         start = __ctsvc_get_content_value(val);
3288         RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
3289
3290         depart = __ctsvc_strtok(start, separator);
3291         contacts_record_set_str(company, _contacts_company.name, __ctsvc_vcard_remove_escape_char(start));
3292
3293         if (depart) {
3294                 __ctsvc_strtok(depart, separator);
3295                 contacts_record_set_str(company, _contacts_company.department, __ctsvc_vcard_remove_escape_char(depart));
3296         }
3297
3298         __ctsvc_vcard_get_company_type(company, prefix);
3299
3300         return CONTACTS_ERROR_NONE;
3301 }
3302
3303 static inline int __ctsvc_vcard_get_company_logo(ctsvc_list_s *company_list, char *prefix, char *val)
3304 {
3305         int ret, type, fd;
3306         gsize size;
3307         guchar *buf;
3308         char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
3309         char *temp;
3310         contacts_record_h company;
3311         struct timeval tv;
3312
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);
3318         }
3319
3320         temp = strchr(val, ':');
3321         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "val is invalid");
3322
3323         *temp = '\0';
3324         type = __ctsvc_vcard_get_image_type((const char *)prefix);
3325
3326         buf = g_base64_decode(temp+1, &size);
3327         if ((0 == size) || (NULL == buf)) {
3328                         /* LCOV_EXCL_START */
3329                 g_free(buf);
3330                 return CONTACTS_ERROR_NONE;
3331                         /* LCOV_EXCL_STOP */
3332         }
3333
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));
3337
3338         fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
3339         if (fd < 0) {
3340                 /* LCOV_EXCL_START */
3341                 g_free(buf);
3342                 ERR("System : open Fail(%d)", errno);
3343                 return CONTACTS_ERROR_SYSTEM;
3344                 /* LCOV_EXCL_STOP */
3345         }
3346
3347         while (0 < size) {
3348                 ret = write(fd, buf, size);
3349                 if (ret <= 0) {
3350                         /* LCOV_EXCL_START */
3351                         if (EINTR == errno) {
3352                                 continue;
3353                         } else {
3354                                 ERR("write() Fail(%d)", errno);
3355                                 close(fd);
3356                                 g_free(buf);
3357                                 if (ENOSPC == errno)
3358                                         return CONTACTS_ERROR_FILE_NO_SPACE;   /* No space */
3359                                 else
3360                                         return CONTACTS_ERROR_SYSTEM;   /* IO error */
3361                         }
3362                         /* LCOV_EXCL_STOP */
3363                 }
3364                 size -= ret;
3365         }
3366
3367         close(fd);
3368         g_free(buf);
3369
3370         ((ctsvc_company_s*)company)->is_vcard = true;
3371         contacts_record_set_str(company, _contacts_company.logo, dest);
3372
3373         return CONTACTS_ERROR_NONE;
3374 }
3375
3376 static inline int __ctsvc_vcard_get_note(ctsvc_list_s *note_list, char *val)
3377 {
3378         int ret;
3379         char *temp;
3380         contacts_record_h note;
3381
3382         ret = contacts_record_create(_contacts_note._uri, &note);
3383         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3384         contacts_list_add((contacts_list_h)note_list, note);
3385
3386         temp = __ctsvc_get_content_value(val);
3387         RETV_IF(NULL == temp, CONTACTS_ERROR_NO_DATA);
3388
3389         contacts_record_set_str(note, _contacts_note.note, __ctsvc_vcard_remove_escape_char(temp));
3390
3391         return CONTACTS_ERROR_NONE;
3392 }
3393
3394 static inline int __ctsvc_vcard_get_time(char *val)
3395 {
3396         int i;
3397         char tmp[10] = {0};
3398         struct tm ts = {0};
3399
3400         i = 0;
3401         while (*val && (*val < '0' || '9' < *val)) val++;
3402         while (*val) {
3403                 tmp[i++] = *val;
3404                 val++;
3405                 if (4 <= i || *val < '0' || '9' < *val) break;
3406         }
3407         tmp[i] = 0;
3408         ts.tm_year = atoi(tmp)-1900;
3409
3410         i = 0;
3411         while (*val && (*val < '0' || '9' < *val)) val++;
3412         while (*val) {
3413                 tmp[i++] = *val;
3414                 val++;
3415                 if (2 <= i || *val < '0' || '9' < *val) break;
3416         }
3417         tmp[i] = 0;
3418         ts.tm_mon = atoi(tmp)-1;
3419
3420         i = 0;
3421         while (*val && (*val < '0' || '9' < *val)) val++;
3422         while (*val) {
3423                 tmp[i++] = *val;
3424                 val++;
3425                 if (2 <= i || *val < '0' || '9' < *val) break;
3426         }
3427         tmp[i] = 0;
3428         ts.tm_mday = atoi(tmp);
3429
3430         i = 0;
3431         while (*val && (*val < '0' || '9' < *val)) val++;
3432         while (*val) {
3433                 tmp[i++] = *val;
3434                 val++;
3435                 if (2 <= i || *val < '0' || '9' < *val) break;
3436         }
3437         tmp[i] = 0;
3438         ts.tm_hour = atoi(tmp);
3439
3440         i = 0;
3441         while (*val && (*val < '0' || '9' < *val)) val++;
3442         while (*val) {
3443                 tmp[i++] = *val;
3444                 val++;
3445                 if (2 <= i || *val < '0' || '9' < *val) break;
3446         }
3447         tmp[i] = 0;
3448         ts.tm_min = atoi(tmp);
3449
3450         i = 0;
3451         while (*val && (*val < '0' || '9' < *val)) val++;
3452         while (*val) {
3453                 tmp[i++] = *val;
3454                 val++;
3455                 if (2 <= i || *val < '0' || '9' < *val) break;
3456         }
3457         tmp[i] = 0;
3458         ts.tm_sec = atoi(tmp);
3459
3460         return (int)mktime(&ts);
3461 }
3462
3463 static inline void __ctsvc_vcard_get_url_type(contacts_record_h url, char *val)
3464 {
3465         char *temp, *result, *last = NULL;
3466         char *lower, *lower_temp;
3467         int type = CONTACTS_URL_TYPE_OTHER;
3468
3469         temp = strtok_r(val, ";", &last);
3470         while (temp) {
3471                 lower = strdup(temp);
3472                 if (NULL == lower) {
3473                         /* LCOV_EXCL_START */
3474                         ERR("strdup() Fail");
3475                         break;
3476                         /* LCOV_EXCL_STOP */
3477                 }
3478                 lower_temp = lower;
3479                 while (*lower_temp) {
3480                         *lower_temp = tolower(*lower_temp);
3481                         lower_temp++;
3482                 }
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-");
3488                 if (result) {
3489                         type = CONTACTS_URL_TYPE_CUSTOM;
3490                         contacts_record_set_str(url, _contacts_url.label, temp+(result-lower)+2);
3491                 }
3492
3493                 free(lower);
3494                 temp = strtok_r(NULL, ";", &last);
3495         }
3496         contacts_record_set_int(url, _contacts_url.type, type);
3497 }
3498
3499 static inline int __ctsvc_vcard_get_url(ctsvc_list_s *url_list, char *prefix, char *val)
3500 {
3501         int ret;
3502         contacts_record_h url;
3503         char *temp;
3504
3505         temp = __ctsvc_get_content_value(val);
3506         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3507
3508         ret = contacts_record_create(_contacts_url._uri, &url);
3509         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3510
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);
3514
3515         return CONTACTS_ERROR_NONE;
3516 }
3517
3518 static inline bool __ctsvc_vcard_get_number_type(contacts_record_h number, char *val)
3519 {
3520         char *temp, *result, *last = NULL;
3521         char *lower, *lower_temp;
3522         int type = CONTACTS_NUMBER_TYPE_OTHER;
3523         bool pref = false;
3524
3525         temp = strtok_r(val, ";", &last);
3526         while (temp) {
3527                 lower = strdup(temp);
3528                 if (NULL == lower) {
3529                         ERR("strdup() Fail");
3530                         break;
3531                 }
3532                 lower_temp = lower;
3533                 while (*lower_temp) {
3534                         *lower_temp = tolower(*lower_temp);
3535                         lower_temp++;
3536                 }
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-");
3566                 if (result) {
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;
3576                         } else {
3577                                 type = CONTACTS_NUMBER_TYPE_CUSTOM;
3578                                 contacts_record_set_str(number, _contacts_number.label, temp+(result-lower)+2);
3579                         }
3580                 /* LCOV_EXCL_STOP */
3581                 }
3582
3583                 free(lower);
3584                 temp = strtok_r(NULL, ";", &last);
3585         }
3586         contacts_record_set_int(number, _contacts_number.type, type);
3587
3588         return pref;
3589 }
3590
3591 static char* __ctsvc_vcard_get_clean_number_for_import(char *str)
3592 {
3593         int char_len = 0;
3594         char *s = SAFE_STR(str);
3595         char *r = s;
3596         while (*s) {
3597                 char_len = __ctsvc_vcard_check_utf8(*s);
3598                 /* LCOV_EXCL_START */
3599                 if (3 == char_len) {
3600                         if (*s == 0xef) {
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);
3604                                                 r++;
3605                                                 s += 3;
3606                                         } else if (0x8b == *(s+2)) {   /* ef bc 8b : '+' */
3607                                                 *r = '+';
3608                                                 r++;
3609                                                 s += 3;
3610                                         } else if (0x8a == *(s+2)) {   /* ef bc 8a : '*' */
3611                                                 *r = '*';
3612                                                 r++;
3613                                                 s += 3;
3614                                         } else if (0x83 == *(s+2)) {   /* ef bc 83 : '#' */
3615                                                 *r = '#';
3616                                                 r++;
3617                                                 s += 3;
3618                                         } else if (0xb0 == *(s+2) || 0x8c == *(s+2)) {   /* ef bc b0 : 'P', ef bc 8c : ',' */
3619                                                 *r = ',';
3620                                                 r++;
3621                                                 s += 3;
3622                                         } else if (0xb7 == *(s+2) || 0x9b == *(s+2)) {   /* ef bc b7 : 'W', ef bc 9b : ';' */
3623                                                 *r = ';';
3624                                                 r++;
3625                                                 s += 3;
3626                                         } else {
3627                                                 s += char_len;
3628                                         }
3629                                 } else if (*(s+1) == 0xbd) {
3630                                         if (0x90 == *(s+2)) {
3631                                                 *r = ',';
3632                                                 r++;
3633                                                 s += 3;
3634                                         } else if (0x97 == *(s+2)) {
3635                                                 *r = ';';
3636                                                 r++;
3637                                                 s += 3;
3638                                         }
3639                                 } else {
3640                                         s += char_len;
3641                                 }
3642                         } else {
3643                                 s += char_len;
3644                         }
3645                 }
3646                 /* LCOV_EXCL_STOP */
3647                 else if (1 == char_len) {
3648                         switch (*s) {
3649                         case '/':
3650                         case '.':
3651                         case '0' ... '9':
3652                         case '#':
3653                         case '*':
3654                         case '(':
3655                         case ')':
3656                         case ',':
3657                         case ';':
3658                         case '+':
3659                                 *r = *s;
3660                                 r++;
3661                                 s++;
3662                                 break;
3663                 /* LCOV_EXCL_START */
3664                         case 'p':
3665                         case 'P':
3666                                 *r = ',';
3667                                 r++;
3668                                 s++;
3669                                 break;
3670                         case 'w':
3671                         case 'W':
3672                                 *r = ';';
3673                                 r++;
3674                                 s++;
3675                                 break;
3676                         case 'a' ... 'o':
3677                 /* LCOV_EXCL_STOP */
3678                         case 'q' ... 'v':
3679                         case 'x' ... 'z':
3680                 /* LCOV_EXCL_START */
3681                                 *r = *s - 0x20;
3682                                 r++;
3683                                 s++;
3684                                 break;
3685                         case 'A' ... 'O':
3686                 /* LCOV_EXCL_STOP */
3687                         case 'Q' ... 'V':
3688                         case 'X' ... 'Z':
3689                 /* LCOV_EXCL_START */
3690                                 *r = *s;
3691                                 r++;
3692                                 s++;
3693                                 break;
3694                         default:
3695                                 s++;
3696                                 break;
3697                 /* LCOV_EXCL_STOP */
3698                         }
3699                 } else {
3700                 /* LCOV_EXCL_START */
3701                         s += char_len;
3702                 /* LCOV_EXCL_STOP */
3703                 }
3704         }
3705         *r = '\0';
3706         return str;
3707 }
3708
3709 static inline int __ctsvc_vcard_get_number(ctsvc_list_s *numbers, char *prefix, char *val)
3710 {
3711         bool is_default;
3712         int ret;
3713         char *temp;
3714         contacts_record_h number;
3715
3716         temp = __ctsvc_get_content_value(val);
3717         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3718
3719         ret = contacts_record_create(_contacts_number._uri, &number);
3720         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3721
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));
3724
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);
3728
3729         return CONTACTS_ERROR_NONE;
3730 }
3731
3732 static inline bool __ctsvc_vcard_get_email_type(contacts_record_h email, char *val)
3733 {
3734         char *temp, *result, *last = NULL;
3735         char *lower, *lower_temp;
3736         int type = CONTACTS_EMAIL_TYPE_OTHER;
3737         bool pref = false;
3738
3739         temp = strtok_r(val, ";", &last);
3740         while (temp) {
3741                 lower = strdup(temp);
3742                 if (NULL == lower) {
3743                         /* LCOV_EXCL_START */
3744                         ERR("strdup() Fail");
3745                         break;
3746                         /* LCOV_EXCL_STOP */
3747                 }
3748                 lower_temp = lower;
3749                 while (*lower_temp) {
3750                         *lower_temp = tolower(*lower_temp);
3751                         lower_temp++;
3752                 }
3753                 if (strstr(lower, "pref"))
3754                         pref = true;
3755
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 */
3767                 }
3768
3769                 free(lower);
3770                 temp = strtok_r(NULL, ";", &last);
3771         }
3772         contacts_record_set_int(email, _contacts_email.type, type);
3773
3774         return pref;
3775 }
3776
3777 static inline int __ctsvc_vcard_get_email(ctsvc_list_s *emails, char *prefix, char *val)
3778 {
3779         bool is_default;
3780         int ret;
3781         char *temp;
3782         contacts_record_h email;
3783
3784         temp = __ctsvc_get_content_value(val);
3785         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3786
3787         ret = contacts_record_create(_contacts_email._uri, &email);
3788         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3789
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);
3794
3795         return CONTACTS_ERROR_NONE;
3796 }
3797
3798 static inline bool __ctsvc_vcard_get_postal_type(contacts_record_h address, char *val)
3799 {
3800         char *temp, *result, *last = NULL;
3801         char *lower, *lower_temp;
3802         int type = CONTACTS_ADDRESS_TYPE_OTHER;
3803         bool pref = false;
3804
3805         temp = strtok_r(val, ";", &last);
3806         while (temp) {
3807                 lower = strdup(temp);
3808                 if (NULL == lower) {
3809                         /* LCOV_EXCL_START */
3810                         ERR("strdup() Fail");
3811                         break;
3812                         /* LCOV_EXCL_STOP */
3813                 }
3814                 lower_temp = lower;
3815                 while (*lower_temp) {
3816                         *lower_temp = tolower(*lower_temp);
3817                         lower_temp++;
3818                 }
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-");
3832                 if (result) {
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 */
3837                 }
3838                 result = strstr(val, "pref");
3839                 if (result) pref = true;
3840
3841                 free(lower);
3842                 temp = strtok_r(NULL, ";", &last);
3843         }
3844
3845         contacts_record_set_int(address, _contacts_address.type, type);
3846
3847         return pref;
3848 }
3849
3850 static inline int __ctsvc_vcard_get_address(ctsvc_list_s *address_list, char *prefix, char *val)
3851 {
3852         char *text;
3853         char *text_temp;
3854         contacts_record_h address;
3855
3856         contacts_record_create(_contacts_address._uri, &address);
3857         if (address) {
3858
3859                 text = strchr(val, ':');
3860                 if (text) {
3861                         text++;
3862                         *(text-1) = '\0';
3863                 } else {
3864                         text = val;
3865                 }
3866
3867                 do {
3868                         bool separator = false;
3869
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);
3877
3878                         ERR("invalid ADR type"); /* LCOV_EXCL_LINE */
3879                 } while (0);
3880
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));
3886                 } else {
3887                         /* LCOV_EXCL_START */
3888                         ERR("Invalid vcard");
3889                         contacts_record_destroy(address, true);
3890                         return CONTACTS_ERROR_INVALID_PARAMETER;
3891                         /* LCOV_EXCL_STOP */
3892                 }
3893                 contacts_list_add((contacts_list_h)address_list, address);
3894         }
3895
3896         return CONTACTS_ERROR_NONE;
3897 }
3898
3899 static inline void __ctsvc_vcard_get_messenger_type(contacts_record_h messenger, char *val)
3900 {
3901         char *temp, *result, *last = NULL;
3902         char *lower, *lower_temp;
3903         int type = CONTACTS_MESSENGER_TYPE_OTHER;
3904
3905         temp = strtok_r(val, ";", &last);
3906         while (temp) {
3907                 lower = strdup(temp);
3908                 if (NULL == lower) {
3909                         ERR("strdup() Fail");
3910                         break;
3911                 }
3912                 lower_temp = lower;
3913                 while (*lower_temp) {
3914                         *lower_temp = tolower(*lower_temp);
3915                         lower_temp++;
3916                 }
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-");
3922                 if (result) {
3923                         type = CONTACTS_MESSENGER_TYPE_CUSTOM;
3924                         contacts_record_set_str(messenger, _contacts_messenger.label, temp+(result-lower)+2);
3925                 }
3926                 free(lower);
3927                 temp = strtok_r(NULL, ";", &last);
3928         }
3929         contacts_record_set_int(messenger, _contacts_messenger.type, type);
3930 }
3931
3932 static inline int __ctsvc_vcard_get_messenger(ctsvc_list_s *messenger_list, int type, char *prefix, char *val)
3933 {
3934         int ret;
3935         contacts_record_h messenger;
3936         char *temp;
3937
3938         temp = __ctsvc_get_content_value(val);
3939         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
3940
3941         ret = contacts_record_create(_contacts_messenger._uri, &messenger);
3942         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
3943
3944         contacts_record_set_str(messenger, _contacts_messenger.im_id, __ctsvc_vcard_remove_escape_char(temp));
3945
3946         switch (type) {
3947                 /* LCOV_EXCL_START */
3948         case CTSVC_VCARD_VALUE_X_MSN:
3949                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_WLM);
3950                 break;
3951         case CTSVC_VCARD_VALUE_X_YAHOO:
3952                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_YAHOO);
3953                 break;
3954         case CTSVC_VCARD_VALUE_X_ICQ:
3955                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_ICQ);
3956                 break;
3957         case CTSVC_VCARD_VALUE_X_AIM:
3958                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_AIM);
3959                 break;
3960         case CTSVC_VCARD_VALUE_X_JABBER:
3961                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_JABBER);
3962                 break;
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);
3966                 break;
3967         case CTSVC_VCARD_VALUE_X_QQ:
3968                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_QQ);
3969                 break;
3970         case CTSVC_VCARD_VALUE_X_GOOGLE_TALK:
3971                 contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_GOOGLE);
3972                 break;
3973                 /* LCOV_EXCL_STOP */
3974         case CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER:
3975                 __ctsvc_vcard_get_messenger_type(messenger, prefix);
3976                 break;
3977         }
3978         contacts_list_add((contacts_list_h)messenger_list, messenger);
3979
3980         return CONTACTS_ERROR_NONE;
3981 }
3982
3983 static inline void __ctsvc_vcard_get_relationship_type(contacts_record_h relationship, char *val)
3984 {
3985         char *temp, *result, *last = NULL;
3986         char *lower, *lower_temp;
3987         int type = CONTACTS_RELATIONSHIP_TYPE_OTHER;
3988
3989         temp = strtok_r(val, ";", &last);
3990         while (temp) {
3991                 lower = strdup(temp);
3992                 if (NULL == lower) {
3993                         /* LCOV_EXCL_START */
3994                         ERR("strdup() Fail");
3995                         break;
3996                         /* LCOV_EXCL_STOP */
3997                 }
3998                 lower_temp = lower;
3999                 while (*lower_temp) {
4000                         *lower_temp = tolower(*lower_temp);
4001                         lower_temp++;
4002                 }
4003
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);
4035                 }
4036                 free(lower);
4037                 temp = strtok_r(NULL, ";", &last);
4038         }
4039         contacts_record_set_int(relationship, _contacts_relationship.type, type);
4040 }
4041
4042
4043 static inline int __ctsvc_vcard_get_relationship(ctsvc_list_s *relationship_list, int type, char *prefix, char *val)
4044 {
4045         int ret;
4046         char *temp;
4047         contacts_record_h relationship;
4048
4049         temp = __ctsvc_get_content_value(val);
4050         RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "vcard");
4051
4052         ret = contacts_record_create(_contacts_relationship._uri, &relationship);
4053         RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Fail(%d)", ret);
4054
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);
4058
4059         return CONTACTS_ERROR_NONE;
4060
4061 }
4062                 /* LCOV_EXCL_START */
4063 static char* __ctsvc_vcard_decode_base64_val(char *val)
4064 {
4065         gsize size = 0;
4066         guchar *decoded_str;
4067         char *src;
4068         char *dest = NULL;
4069
4070         src = strchr(val, ':');
4071         if (NULL == src)
4072                 src = val;
4073         else
4074                 src++;
4075
4076         decoded_str = g_base64_decode(src, &size);
4077
4078         dest = calloc((src-val)+size+1, sizeof(char));
4079         if (NULL == dest) {
4080                 g_free(decoded_str);
4081                 ERR("calloc() Fail");
4082                 return NULL;
4083         }
4084
4085         snprintf(dest, (src-val)+1, "%s", val);
4086         snprintf(dest+(src-val), size+1, "%s", decoded_str);
4087         g_free(decoded_str);
4088
4089         return dest;
4090 }
4091                 /* LCOV_EXCL_STOP */
4092 static inline int __ctsvc_vcard_get_contact(int ver, char *vcard, contacts_record_h *record)
4093 {
4094         int type;
4095         char *cursor, *new_start, *val, *prefix;
4096         ctsvc_contact_s *contact = (ctsvc_contact_s*)*record;
4097
4098         cursor = vcard;
4099         while (cursor) {
4100                 val = NULL;
4101                 prefix = NULL;
4102
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);
4108                         if (new_start) {
4109                                 cursor = new_start;
4110                                 continue;
4111                 /* LCOV_EXCL_STOP */
4112                         } else {
4113                                 break;
4114                         }
4115                 }
4116
4117                 if (CTSVC_VCARD_VALUE_PHOTO != type && CTSVC_VCARD_VALUE_LOGO != type)
4118                         base64_encoded = __ctsvc_vcard_check_base64_encoded(cursor);
4119
4120                 new_start = __ctsvc_vcard_get_val(ver, cursor, &prefix, &val);
4121                 /* LCOV_EXCL_START */
4122                 if (NULL == new_start) {
4123                         if (prefix)
4124                                 free(prefix);
4125                         if (val)
4126                                 free(val);
4127                         continue;
4128                 }
4129
4130                 if (NULL == val) {
4131                         cursor = new_start;
4132                         if (prefix)
4133                                 free(prefix);
4134                         continue;
4135                 }
4136                 if (base64_encoded) {
4137                         char *temp = __ctsvc_vcard_decode_base64_val(val);
4138                         if (NULL == temp) {
4139                                 ERR("__ctsvc_vcard_decode_base64_val() Fail");
4140                                 free(prefix);
4141                                 free(val);
4142                                 return CONTACTS_ERROR_OUT_OF_MEMORY;
4143                         }
4144                         free(val);
4145                         val = temp;
4146                 }
4147                                 /* LCOV_EXCL_STOP */
4148                 switch (type) {
4149                 case CTSVC_VCARD_VALUE_FN:
4150                         __ctsvc_vcard_get_display_name(contact->name, val);
4151                         break;
4152                 case CTSVC_VCARD_VALUE_N:
4153                         __ctsvc_vcard_get_name(contact->name, val);
4154                         break;
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);
4159                         break;
4160                 case CTSVC_VCARD_VALUE_NICKNAME:
4161                         __ctsvc_vcard_get_nickname(contact->nicknames, val);
4162                         break;
4163                 case CTSVC_VCARD_VALUE_PHOTO:
4164                         __ctsvc_vcard_get_photo(*record, contact->images, prefix, val);
4165                         break;
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);
4170                         break;
4171                 case CTSVC_VCARD_VALUE_ADR:
4172                         __ctsvc_vcard_get_address(contact->postal_addrs, prefix, val);
4173                         break;
4174                 case CTSVC_VCARD_VALUE_TEL:
4175                         __ctsvc_vcard_get_number(contact->numbers, prefix, val);
4176                         break;
4177                 case CTSVC_VCARD_VALUE_EMAIL:
4178                         __ctsvc_vcard_get_email(contact->emails, prefix, val);
4179                         break;
4180                 case CTSVC_VCARD_VALUE_TITLE:
4181                         __ctsvc_vcard_get_company_value(contact->company, _contacts_company.job_title, val);
4182                         break;
4183                 case CTSVC_VCARD_VALUE_ROLE:
4184                         __ctsvc_vcard_get_company_value(contact->company, _contacts_company.role, val);
4185                         break;
4186                 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION:
4187                         __ctsvc_vcard_get_company_value(contact->company, _contacts_company.location, val);
4188                         break;
4189                 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION:
4190                         __ctsvc_vcard_get_company_value(contact->company, _contacts_company.description, val);
4191                         break;
4192                 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME:
4193                         __ctsvc_vcard_get_company_value(contact->company, _contacts_company.phonetic_name, val);
4194                         break;
4195                 case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME:
4196                         __ctsvc_vcard_get_company_value(contact->company, _contacts_company.assistant_name, val);
4197                         break;
4198                 case CTSVC_VCARD_VALUE_LOGO:
4199                         __ctsvc_vcard_get_company_logo(contact->company, prefix, val);
4200                         break;
4201                 case CTSVC_VCARD_VALUE_ORG:
4202                         __ctsvc_vcard_get_company(contact->company, prefix, val);
4203                         break;
4204                 case CTSVC_VCARD_VALUE_NOTE:
4205                         __ctsvc_vcard_get_note(contact->note, val);
4206                         break;
4207                 case CTSVC_VCARD_VALUE_REV:
4208                         if (*val)
4209                                 contact->changed_time = __ctsvc_vcard_get_time(val);
4210                         break;
4211                 case CTSVC_VCARD_VALUE_UID:
4212                         contacts_record_set_str((contacts_record_h)contact, _contacts_contact.uid, __ctsvc_vcard_remove_escape_char(val));
4213                         break;
4214                 case CTSVC_VCARD_VALUE_URL:
4215                         __ctsvc_vcard_get_url(contact->urls, prefix, val);
4216                         break;
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);
4228                         break;
4229
4230                 case CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP:
4231                         __ctsvc_vcard_get_relationship(contact->relationships, type, prefix, val);
4232                         break;
4233                 case CTSVC_VCARD_VALUE_END:
4234                         free(val);
4235                         free(prefix);
4236                         return CONTACTS_ERROR_NONE;
4237                 default:
4238                         /* LCOV_EXCL_START */
4239                         ERR("__ctsvc_vcard_check_content_type() Fail(%d)", type);
4240                         free(val);
4241                         free(prefix);
4242                         return CONTACTS_ERROR_INVALID_PARAMETER;
4243                         /* LCOV_EXCL_STOP */
4244                 }
4245                 free(val);
4246                 free(prefix);
4247                 cursor = new_start;
4248         }
4249         /* LCOV_EXCL_START */
4250         ERR("Invalid vcard");
4251         return CONTACTS_ERROR_INVALID_PARAMETER;
4252         /* LCOV_EXCL_STOP */
4253 }
4254
4255 static inline int __ctsvc_vcard_check_version(const char *src)
4256 {
4257         bool start = false;
4258         const char *ver3 = "3.0";
4259
4260         while (*src) {
4261                 switch (*src) {
4262                 case '\n':
4263                 case '\r':
4264                         return CTSVC_VCARD_VER_2_1;
4265                 /* LCOV_EXCL_START */
4266                 case ' ':
4267                         src++;
4268                         break;
4269                 /* LCOV_EXCL_STOP */
4270                 default:
4271                         start = true;
4272                         break;
4273                 }
4274                 if (start) break;
4275         }
4276
4277         if (STRING_EQUAL == strcmp(src, ver3))
4278                 return CTSVC_VCARD_VER_3_0;
4279         else
4280                 return CTSVC_VCARD_VER_2_1;
4281 }
4282
4283 static inline void __ctsvc_vcard_make_contact_display_name(ctsvc_contact_s *contact)
4284 {
4285         ctsvc_name_s *name = NULL;
4286
4287         free(contact->display_name);
4288         contact->display_name = NULL;
4289
4290         free(contact->reverse_display_name);
4291         contact->reverse_display_name = NULL;
4292
4293         if (0 < contact->name->count && contact->name->records
4294                         && contact->name->records->data) {
4295                 name = (ctsvc_name_s*)contact->name->records->data;
4296         }
4297
4298         if (name && (name->first || name->last || name->prefix || name->addition
4299                                 || name->suffix)) {
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;
4307
4308                 /*
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
4315                  */
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");
4326                                 return;
4327                                 /* LCOV_EXCL_STOP */
4328                         }
4329
4330                         len = 0;
4331
4332                         if (name->last) {
4333                                 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
4334
4335                                 if (reverse_lang_type < 0)
4336                                         reverse_lang_type = ctsvc_check_language_type(temp_display);
4337
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, ",");
4343                                 }
4344                         }
4345
4346                         if (reverse_lang_type < 0) {
4347                                 if (*temp_display)
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);
4353                         }
4354
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) {
4359                                         if (*temp_display)
4360                                                 len += snprintf(temp_display + len, temp_display_len - len, " ");
4361                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
4362                                 }
4363
4364                                 if (name->first) {
4365                                         if (*temp_display)
4366                                                 len += snprintf(temp_display + len, temp_display_len - len, " ");
4367                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
4368                                 }
4369                 /* LCOV_EXCL_STOP */
4370                         } else {
4371                                 /* make temp_display name Prefix - Last - First -Middle - Suffix */
4372                                 if (name->first) {
4373                                         if (*temp_display) {
4374                                                 if (reverse_lang_type < 0)
4375                                                         reverse_lang_type = ctsvc_check_language_type(temp_display);
4376
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, " ");
4380                                         }
4381                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
4382                                 }
4383
4384                                 if (name->addition) {
4385                                         if (*temp_display) {
4386                                                 if (reverse_lang_type < 0)
4387                                                         reverse_lang_type = ctsvc_check_language_type(temp_display);
4388
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, " ");
4392                                         }
4393                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
4394                                 }
4395                         }
4396
4397                         if (name->suffix) {
4398                                 if (*temp_display) {
4399                                         if (reverse_lang_type < 0)
4400                                                 reverse_lang_type = ctsvc_check_language_type(temp_display);
4401
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, ", ");
4407                                         }
4408                                 }
4409                                 len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
4410                         }
4411                 }
4412
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");
4419                                 free(temp_display);
4420                                 return;
4421                                 /* LCOV_EXCL_STOP */
4422                         }
4423                         snprintf(reverse_display, display_len, "%s %s", name->prefix, temp_display);
4424                         free(temp_display);
4425                 } else if (temp_display) {
4426                         reverse_display = temp_display;
4427                 } else if (name->prefix) {
4428                         reverse_display = strdup(name->prefix);
4429                 }
4430
4431                 /*
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
4438                  */
4439
4440                 if (reverse_lang_type == CTSVC_LANG_KOREAN ||
4441                                 reverse_lang_type == CTSVC_LANG_CHINESE) {
4442                         display = strdup(reverse_display);
4443                 } else {
4444                         int lang_type = -1;
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);
4458                                         return;
4459                                         /* LCOV_EXCL_STOP */
4460                                 }
4461
4462                                 len = 0;
4463
4464                                 if (name->first) {
4465                                         if (*temp_display)
4466                                                 len += snprintf(temp_display + len, temp_display_len - len, " ");
4467                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
4468                                 }
4469
4470                                 if (name->addition) {
4471                                         if (*temp_display)
4472                                                 len += snprintf(temp_display + len, temp_display_len - len, " ");
4473                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
4474                                 }
4475
4476                                 if (name->last) {
4477                                         if (*temp_display)
4478                                                 len += snprintf(temp_display + len, temp_display_len - len, " ");
4479                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
4480                                 }
4481
4482                                 if (name->suffix) {
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, " ");
4487                                                 else
4488                                                         len += snprintf(temp_display + len, temp_display_len - len, ", ");
4489                                         }
4490                                         len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
4491                                 }
4492                         }
4493
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");
4500                                         free(temp_display);
4501                                         free(reverse_display);
4502                                         return;
4503                                         /* LCOV_EXCL_STOP */
4504                                 }
4505                                 snprintf(display, display_len, "%s %s", name->prefix, temp_display);
4506                                 free(temp_display);
4507                         } else if (temp_display) {
4508                                 display = temp_display;
4509                         } else if (name->prefix) {
4510                                 display = strdup(name->prefix);
4511                         }
4512                 }
4513
4514 #ifdef _CONTACTS_IPC_CLIENT
4515                 contacts_setting_get_name_display_order(&name_display_order);
4516 #endif
4517                 if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == name_display_order) {
4518                         contact->display_name = display;
4519                         free(reverse_display);
4520 #ifdef _CONTACTS_IPC_CLIENT
4521                 } else {
4522                         contact->display_name = reverse_display;
4523                         free(display);
4524 #endif
4525                 }
4526                 contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME;
4527         } else {
4528                 /* LCOV_EXCL_START */
4529                 GList *cur;
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;
4538                                         break;
4539                                 }
4540                         }
4541                 }
4542
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;
4551                                         break;
4552                                 }
4553                         }
4554                 }
4555
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;
4564                                         break;
4565                                 }
4566                         }
4567                 }
4568
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;
4577                                         break;
4578                                 }
4579                         }
4580                 }
4581                 /* LCOV_EXCL_STOP */
4582         }
4583         return;
4584 }
4585
4586 static void __ctsvc_vcard_update_contact_has_properties(ctsvc_contact_s *contact)
4587 {
4588         if (contact->numbers && 0 < contact->numbers->count)
4589                 contact->has_phonenumber = true;
4590
4591         if (contact->emails && 0 < contact->emails->count)
4592                 contact->has_email = true;
4593 }
4594
4595 static int __ctsvc_vcard_parse(const void *vcard_stream, contacts_record_h *record)
4596 {
4597         int ret, ver;
4598         ctsvc_contact_s *contact;
4599         char *val_begin, *new_start, *val;
4600         char *vcard = (char *)vcard_stream;
4601
4602         RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
4603
4604         __ctsvc_vcard_initial();
4605
4606         vcard = __ctsvc_vcard_check_word(vcard, "BEGIN:VCARD");
4607         RETVM_IF(NULL == vcard, CONTACTS_ERROR_INVALID_PARAMETER, "The vcard is invalid.");
4608
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;
4613         } else {
4614                 ver = __ctsvc_vcard_check_version(val);
4615                 free(val);
4616                 vcard = new_start;
4617         }
4618
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");
4621
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);
4627                 return ret;
4628                 /* LCOV_EXCL_STOP */
4629         }
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;
4634 }
4635
4636 #define CTSVC_VCARD_MAX_SIZE 1024*1024
4637
4638 static const char* __contacts_vcard_remove_line_break(const char *c)
4639 {
4640         while (c) {
4641                 if ('\r' == *c && '\n' == *(c+1))
4642                         c += 2;
4643                 else if ('\n' == *c)
4644                         c++;
4645                 else
4646                         break;
4647         }
4648         return c;
4649 }
4650
4651 typedef struct {
4652         const char *pos_start;
4653         const char *pos_end;
4654 } sub_vcard_info_s;
4655
4656 static void __contacts_vcard_free_sub_vcard_info_list(GList *list)
4657 {
4658         if (NULL == list)
4659                 return;
4660
4661         GList *cursor;
4662                 /* LCOV_EXCL_START */
4663         for (cursor = list; cursor; cursor = cursor->next) {
4664                 sub_vcard_info_s *vcard_info = cursor->data;
4665                 free(vcard_info);
4666         }
4667                 /* LCOV_EXCL_STOP */
4668         g_list_free(list);
4669 }
4670
4671 static void __contacts_vcard_free_vcard_object_list(GList *list)
4672 {
4673         if (NULL == list)
4674                 return;
4675
4676         GList *cursor;
4677         for (cursor = list; cursor; cursor = cursor->next) {
4678                 char *vcard_object = cursor->data;
4679                 free(vcard_object);
4680         }
4681         g_list_free(list);
4682
4683 }
4684
4685 static const char* __contacts_vcard_parse_get_vcard_object(const char *cursor, GList **plist_vcard_object)
4686 {
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;
4694
4695         RETV_IF(NULL == plist_vcard_object, cursor);
4696
4697         *plist_vcard_object = NULL;
4698
4699         vcard_start_cursor = __contacts_vcard_remove_line_break(vcard_start_cursor);
4700
4701         if (STRING_EQUAL != strncmp(vcard_start_cursor, begin, strlen(begin)))
4702                 return vcard_start_cursor;
4703
4704         vcard_cursor = vcard_start_cursor;
4705
4706         vcard_cursor += strlen(begin);
4707         vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
4708
4709         while (*vcard_cursor) {
4710                 if (new_line) {
4711                         if (STRING_EQUAL == strncmp(vcard_cursor, end, strlen(end))) {
4712                                 GList *sub_vcard_cursor = NULL;
4713                                 int vcard_len = 0;
4714                                 const char *pos_start = NULL;
4715
4716                                 vcard_cursor += strlen(end);
4717                                 vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
4718
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;
4726                                 }
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);
4734                                         return NULL;
4735                                         /* LCOV_EXCL_STOP */
4736                                 }
4737
4738                                 vcard_len = 0;
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;
4747                                 }
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);
4752
4753                                 return vcard_cursor;
4754                         } else if (STRING_EQUAL == strncmp(vcard_cursor, begin, strlen(begin))) {
4755                                         /* LCOV_EXCL_START */
4756                                 /* sub vcard */
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);
4761                                         return NULL;
4762                                         /* LCOV_EXCL_STOP */
4763                                 }
4764                                 sub_vcard_info->pos_start = vcard_cursor;
4765
4766                                 vcard_cursor = __contacts_vcard_parse_get_vcard_object(vcard_cursor, plist_vcard_object);
4767                                 sub_vcard_info->pos_end = vcard_cursor;
4768
4769                                 sub_vcard_list = g_list_append(sub_vcard_list, sub_vcard_info);
4770                                 continue;
4771                                         /* LCOV_EXCL_STOP */
4772                         }
4773                         new_line = false;
4774                 }
4775                 vcard_cursor++;
4776                 if (('\n' == *vcard_cursor) || ('\r' == *vcard_cursor && '\n' == *(vcard_cursor+1))) {
4777                         new_line = true;
4778                         vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
4779                 }
4780         }
4781                                         /* LCOV_EXCL_START */
4782         __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
4783
4784         return vcard_cursor;
4785                                         /* LCOV_EXCL_STOP */
4786 }
4787
4788 EXPORT_API int contacts_vcard_parse_to_contacts(const char *vcard_stream, contacts_list_h *out_contacts)
4789 {
4790         CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
4791         int ret;
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;
4797
4798         RETV_IF(NULL == out_contacts, CONTACTS_ERROR_INVALID_PARAMETER);
4799         *out_contacts = NULL;
4800
4801         RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
4802
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)
4807                         break;
4808
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 */
4813
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);
4820                                 return ret;
4821                                 /* LCOV_EXCL_STOP */
4822                         }
4823
4824                         if (NULL == list)
4825                                 contacts_list_create(&list);
4826                         contacts_list_add(list, record);
4827                         vcard_object = NULL;
4828                 }
4829                 __contacts_vcard_free_vcard_object_list(list_vcard_object);
4830         }
4831         *out_contacts = list;
4832         return CONTACTS_ERROR_NONE;
4833 }
4834
4835
4836 static int  _ctsvc_safe_add(unsigned int *total, unsigned int value)
4837 {
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 */
4843         }
4844
4845         *total += value;
4846         return CONTACTS_ERROR_NONE;
4847 }
4848
4849 EXPORT_API int contacts_vcard_parse_to_contact_foreach(const char *vcard_file_name,
4850                 contacts_vcard_parse_cb cb, void *data)
4851 {
4852         CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
4853         contacts_record_h record;
4854         FILE *file;
4855         unsigned int buf_size, len;
4856         int written_len;
4857         int ret;
4858         int vcard_depth = 0;
4859         char *stream;
4860         char line[1024] = {0};
4861
4862         RETV_IF(NULL == vcard_file_name, CONTACTS_ERROR_INVALID_PARAMETER);
4863         RETV_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER);
4864
4865         file = fopen(vcard_file_name, "r");
4866         RETVM_IF(NULL == file, CONTACTS_ERROR_SYSTEM, "fopen() Fail(%d)", errno);
4867
4868         len = 0;
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");
4874                 fclose(file);
4875                 return CONTACTS_ERROR_OUT_OF_MEMORY;
4876                 /* LCOV_EXCL_STOP */
4877         }
4878
4879         while (fgets(line, sizeof(line), file)) {
4880                 if (0 == len)
4881                         if (STRING_EQUAL != strncmp(line, "BEGIN:VCARD", strlen("BEGIN:VCARD")))
4882                                 /* LCOV_EXCL_START */
4883                                 continue;
4884                 if (buf_size - len <= strlen(line)) {
4885                         char *new_stream;
4886                         buf_size += sizeof(line) * 2;
4887                         new_stream = realloc(stream, buf_size);
4888                         if (new_stream) {
4889                                 stream = new_stream;
4890                         } else {
4891                                 free(stream);
4892                                 fclose(file);
4893                                 return CONTACTS_ERROR_OUT_OF_MEMORY;
4894                                 /* LCOV_EXCL_STOP */
4895                         }
4896                 }
4897                 written_len = snprintf(stream + len, buf_size - len, "%s", line);
4898                 if (written_len < 0) {
4899                         /* LCOV_EXCL_START */
4900                         free(stream);
4901                         fclose(file);
4902                         ERR("snprintf() Fail(%d)", written_len);
4903                         return CONTACTS_ERROR_SYSTEM;
4904                         /* LCOV_EXCL_STOP */
4905                 }
4906
4907                 ret = _ctsvc_safe_add(&len, (unsigned int)written_len);
4908                 if (CONTACTS_ERROR_NONE != ret) {
4909                         /* LCOV_EXCL_START */
4910                         free(stream);
4911                         fclose(file);
4912                         ERR("_ctsvc_safe_add() Fail(len:%d, written_len:%d)", len, written_len);
4913                         return ret;
4914                         /* LCOV_EXCL_STOP */
4915                 }
4916
4917                 if (STRING_EQUAL == strncmp(line, "END:VCARD", 9)) {
4918                         vcard_depth--;
4919
4920                         if (0 == vcard_depth) {
4921                                 const char *cursor = stream;
4922                                 GList *list_vcard_object = NULL;
4923
4924                                 len = 0;
4925
4926                                 while ((cursor = __contacts_vcard_parse_get_vcard_object(cursor, &list_vcard_object))) {
4927                                         GList *vcard_cursor = NULL;
4928                                         if (NULL == list_vcard_object)
4929                                                 break;
4930
4931                                         for (vcard_cursor = list_vcard_object; vcard_cursor; vcard_cursor = vcard_cursor->next) {
4932                                                 char *vcard_object = vcard_cursor->data;
4933
4934                                                 if (NULL == vcard_object)
4935                                                         continue; /* LCOV_EXCL_LINE */
4936
4937                                                 ret = __ctsvc_vcard_parse(vcard_object, &record);
4938                                                 if (ret < CONTACTS_ERROR_NONE) {
4939                                                         /* LCOV_EXCL_START */
4940                                                         ERR("vcard stream parsing error");
4941                                                         free(stream);
4942                                                         fclose(file);
4943                                                         __contacts_vcard_free_vcard_object_list(list_vcard_object);
4944                                                         return ret;
4945                                                         /* LCOV_EXCL_STOP */
4946                                                 }
4947
4948                                                 if (false == cb(record, data)) {
4949                                                         free(stream);
4950                                                         fclose(file);
4951                                                         __contacts_vcard_free_vcard_object_list(list_vcard_object);
4952                                                         contacts_record_destroy(record, true);
4953                                                         return CONTACTS_ERROR_NONE;
4954                                                 }
4955                                                 contacts_record_destroy(record, true);
4956                                         }
4957                                         __contacts_vcard_free_vcard_object_list(list_vcard_object);
4958                                         list_vcard_object = NULL;
4959                                 }
4960                         }
4961                 } else if (STRING_EQUAL == strncmp(line, "BEGIN:VCARD", 11)) { /* sub vcard object */
4962                         vcard_depth++;
4963                 }
4964         }
4965
4966         free(stream);
4967         fclose(file);
4968         return CONTACTS_ERROR_NONE;
4969 }
4970
4971 EXPORT_API int contacts_vcard_get_entity_count(const char *vcard_file_name, int *count)
4972 {
4973         CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
4974         FILE *file;
4975         int cnt;
4976         char line[1024] = {0};
4977         RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
4978         *count = 0;
4979
4980         RETV_IF(NULL == vcard_file_name, CONTACTS_ERROR_INVALID_PARAMETER);
4981
4982         file = fopen(vcard_file_name, "r");
4983         RETVM_IF(NULL == file, CONTACTS_ERROR_SYSTEM, "System : fopen() Fail(%d)", errno);
4984
4985         cnt = 0;
4986         while (fgets(line, sizeof(line), file)) {
4987                 if (STRING_EQUAL == strncmp(line, "END:VCARD", 9))
4988                         cnt++;
4989         }
4990         fclose(file);
4991
4992         *count = cnt;
4993
4994         return CONTACTS_ERROR_NONE;
4995 }
4996
4997 EXPORT_API int contacts_vcard_get_limit_size_of_photo(unsigned int *limit_size)
4998 {
4999         CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
5000 #ifdef _CONTACTS_IPC_CLIENT
5001         int ret;
5002         bool result = false;
5003 #endif
5004
5005         RETV_IF(NULL == limit_size, CONTACTS_ERROR_INVALID_PARAMETER);
5006
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)");
5011 #endif
5012
5013         *limit_size = limit_size_of_photo;
5014         return CONTACTS_ERROR_NONE;
5015 }
5016
5017 EXPORT_API int contacts_vcard_set_limit_size_of_photo(unsigned int limit_size)
5018 {
5019         CHECK_CONTACT_SUPPORTED(CONTACT_FEATURE);
5020 #ifdef _CONTACTS_IPC_CLIENT
5021         int ret;
5022         bool result = false;
5023 #endif
5024
5025         RETV_IF(CTSVC_IMAGE_MAX_SIZE <= limit_size, CONTACTS_ERROR_INVALID_PARAMETER);
5026         RETV_IF(limit_size < 8, CONTACTS_ERROR_INVALID_PARAMETER);
5027
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)");
5032 #endif
5033
5034         limit_size_of_photo = limit_size;
5035         return CONTACTS_ERROR_NONE;
5036 }
5037