Modify flora license version.
[platform/core/messaging/msg-service.git] / vobject-engine / VCard.c
1 /*
2 * Copyright 2012-2013  Samsung Electronics Co., Ltd
3 *
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *    http://floralicense.org/license/
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "VTypes.h"
18 #include "VCard.h"
19 #include "vobject.h"
20
21 #define MAX_TYPE_NAME_LEN 50
22 #define MAX_PARAM_NAME_LEN 50
23 #define CHECK_START 1
24 #define CHECK_END 2
25
26 #define VFREE(obj) if(obj != NULL) { /*VDATA_TRACE("%p",obj);*/ free(obj); \
27         obj = NULL; \
28 }
29
30 #define TRIM(obj) if(obj != NULL) {\
31         _VRLSpace(obj);\
32         _VRTSpace(obj);\
33 }
34
35 #define UPPER(obj,start,end) if(obj != NULL) {\
36         for(start = 0; start < end; start++)\
37                 obj[start] = toupper(obj[start]);\
38 }
39
40 #define GO_NEXT_CHAR(current, rowData, addedCnt) {\
41         current = *rowData;\
42         rowData++;\
43         (*addedCnt)++;\
44 }
45
46 #define SET_PARAM_VALUE(PARAM, SZVALUE, LIST, LISTCNT, PARAMOBJ, PTYPE, ENC) {\
47         PARAM = 0;\
48         PARAM |= __VCardGetValue(SZVALUE, LIST, LISTCNT);\
49         if ( PARAM != UNKNOWN_NAME ) {\
50                 PARAMOBJ->parameter = PTYPE;\
51                 if(PTYPE == VCARD_PARAM_ENCODING)\
52                         ENC = PARAM;\
53                 break;\
54         }\
55 }
56
57 #define LENGTH_TYPE_LIST(obj, len) for(len =0; obj[len] != NULL; len++);
58
59 extern char* _VUnfoldingNoSpecNew( char *string );
60
61 /** GLOBAL VARIABLE DECLARATION AND INITIALIZATION */
62 /** vCard Types. */
63 char* pszCardTypeList[] =
64 {
65         "ADR",                  /* Delivery Address -> address*/
66         "AGENT",                        /* Agent -> assistant name, assistant number*/
67         "BDAY",                 /* Birthday -> birthday */
68         "BEGIN",                        /* BEGIN VCARD DELIMITER*/
69         "CATEGORIES",   /* Categories is a multivalued attribute */
70         "CLASS",                        /* */
71         "EMAIL",                        /* Email -> email */
72         "END",                  /* END VCARD DELIMITER*/
73         "FN",                   /* Formatted Name -> display_name */
74         "GEO",                  /* Geographic Positioning*/
75         "KEY",                  /* Public Key*/
76         "LABEL",                        /* Label Address -> address*/
77         "LOGO",                 /* Logo*/
78         "MAILER",               /* Email Program (Optional)*/
79         "N",                            /* Name -> name */
80         "NAME",                 /* Name -> name */
81         "NICKNAME",             /* Nickname -> nickname */
82         "NOTE",                 /* Note -> note */
83         "ORG",                  /* Organization Name or Organizational unit -> department*/
84         "PHOTO",                        /* Photograph -> caller id*/
85         "PRODID",               /* */
86         "PROFILE",              /* */
87         "REV",                  /* Last Revision(combination of calendar date & time)*/
88         "ROLE",                 /* Role or occupation */
89         "SORT-STRING",  /* */
90         "SOUND",                        /* Sound*/
91         "SOURCE",               /* */
92         "TEL",                  /* Telephone -> phone number */
93         "TITLE",                        /* Job Title -> job title */
94         "TZ",                   /* Time Zone*/
95         "UID",                  /* Unique Identifier*/
96         "URL",                  /* URL -> web address */
97         "VERSION",              /* Version*/
98         "X-IRMC-LUID",  /* */
99         NULL
100 };
101
102 /** Parameter */
103 char* pszCardParamList[] =
104 {
105         "CHARSET",
106         "CONTEXT",
107         "ENCODING",
108         "LANGUAGE",
109         "TYPE",
110         "VALUE"
111 };
112
113 /** Encoding value */
114 ValueObj pEncList[] =
115 {
116         {"B",                   0x00000001},
117         {"BASE64",      0x00000002},
118         {"QUOTED-PRINTABLE", 0x00000004},
119         {"7BIT",                0x00000008},
120         {"8BIT",                0x00000010}
121 };
122
123 /** Character set value */
124 ValueObj pCharsetList[] =
125 {
126         {"UTF-8",                       0x00000001},
127         {"UTF-16",              0x00000002},
128         {"ISO-8859-1",  0x00000004}
129 };
130
131 /** Value value */
132 ValueObj pValueList[] =
133 {
134         {"BINARY",                      0x00000001},
135         {"BOOLEAN",                     0x00000002},
136         {"DATE",                                0x00000004},
137         {"DATE-TIME",           0x00000008},
138         {"FLOAT",                               0x00000010},
139         {"INTEGER",                     0x00000020},
140         {"PHONE-NUMBER",        0x00000040},
141         {"TEXT",                                0x00000080},
142         {"TIME",                                0x00000100},
143         {"URI",                                 0x00000200},
144         {"URL",                                 0x00000400},
145         {"UTC-OFFSET",          0x00000800},
146         {"VCARD",                               0x00001000}
147 };
148
149 /** Type value */
150 ValueObj pTypeList[] =
151 {
152         {"AIFF",                0x00000001},
153         {"BBS",                 0x00000002},
154         {"CAR",                 0x00000004},
155         {"CELL",                0x00000008},
156         {"DOM",                 0x00000010},
157         {"WORK",                0x00000020},
158         {"FAX",                 0x00000040},
159         {"GIF",                 0x00000080},
160         {"HOME",                0x00000100},
161         {"INTL",                0x00000200},
162         {"INTERNET",    0x00000400},
163         {"ISDN",                0x00000800},
164         {"JPEG",                0x00001000},
165         {"MOBILE",      0x00002000},
166         {"MODEM",               0x00004000},
167         {"MSG",                 0x00008000},
168         {"PAGER",               0x00010000},
169         {"PARCEL",      0x00020000},
170         {"PCM",                 0x00040000},
171         {"PCS",                 0x00080000},
172         {"PNG",                 0x00100000},
173         {"POSTAL",      0x00200000},
174         {"PREF",                0x00400000},
175         {"VIDEO",               0x00800000},
176         {"VOICE",               0x01000000},
177         {"WAVE",                0x02000000},
178         {"WBMP",                0x04000000},
179         {"ETC",                 0x08000000},
180         {"X400",                0x10000000}
181 };
182
183 /** FUNCTION DECLARATION        */
184 int __VCardGetName(char*, char**, int);
185 int __VCardGetValue(char*, const ValueObj*, int);
186 int __VCardGetTypeName(char*, int*, int*);
187 int __VCardGetParamName(char*, int*, int*);
188 int __VIsVcardFile(char*, int);
189 char* __VCardGetParamVal(char*,int*, int*);
190 char* __VCardGetTypeVal(char*, int*, int*, int, VObject*);
191 char* __VCardTypeEncode(VObject*, char*);
192 char* __VCardParamEncode(VObject*, int*);
193
194 #ifdef VDATA_GROUPNAME_SUPPORTED
195 char*   gszGroupName;
196 #endif // VDATA_GROUPNAME_SUPPORTED
197
198
199 /**
200  * __VCardGetName() compares the string and vCard type, parameter name.
201  *
202  * @param       szString        Name which will compare
203  * @param               pszList[]               Name list of vCard type and param
204  * @param               size                            Number of total element of list
205  *
206  * @return      index           The index in the list
207  */
208 int
209 __VCardGetName(char* szString, char* pszList[], int size)
210 {
211         VDATA_TRACE_BEGINE
212         int high, low, i, diff;
213
214         low = 0;
215         high = size - 1;
216
217         for(; high >= low; diff<0 ? (low = i+1):(high = i-1)) {
218                 i = ( low + high ) / 2;
219                 if((diff = strcmp( pszList[i], szString )) == 0) /* success: found it */
220                         return i;
221         }
222         VDATA_TRACE_END
223         return UNKNOWN_NAME;
224 }
225
226 /**
227  * __VCardGetValue() compares the string and vCard type, parameter value.
228  *
229  * @param       szString        Value which will compare
230  * @param               list[]          Value list of vCard param
231  * @param               size                    Number of total element of list
232  *
233  * @return      flag      The value's flag.
234  */
235 int
236 __VCardGetValue( char* szString, const ValueObj list[], int size)
237 {
238         VDATA_TRACE_BEGINE
239         int i = 0, diff = -1;
240         char* szTemp = szString;
241
242         SysRequireEx(szString, UNKNOWN_NAME);
243         SysRequireEx(size > 0, UNKNOWN_NAME);
244
245         UPPER(szTemp,i,strlen(szTemp));
246
247         for(i = 0; i < size-1; i++)
248         {
249                 VDATA_TRACE(" i : %d",i);
250                 VDATA_TRACE(" for loop %d < %d, list[%d] : %p, list[%d].szName : %p",i,size,i,list[i],i,list[i].szName);
251                 VDATA_TRACE(" i : %d",i);
252                 if(list[i].szName != NULL)
253                 {
254                         VDATA_TRACE(" list[%d].szName != NULL",i);
255                         VDATA_TRACE(" before strcmp %s %s",list[i].szName,szTemp);
256                         VDATA_TRACE(" before strcmp %d",strcmp(list[i].szName, szTemp));
257                         if((diff = strcmp(list[i].szName, szTemp)) == 0) /* success: found it */
258                         {
259                                 VDATA_TRACE(" return %d",list[i].flag);
260                                 VDATA_TRACE_END
261                                 return list[i].flag;
262                         }
263                         VDATA_TRACE(" after strcmp %s %s",list[i].szName,szTemp);
264                 }
265         }
266         VDATA_TRACE(" return UNKNOWN_NAME");
267         VDATA_TRACE_END
268         return UNKNOWN_NAME;
269 }
270
271 /**
272  * __VCardGetTypeName() fine the type name and returns the index number
273  *
274  * @param               pVCardRaw       The raw data
275  * @param               pStatus         Decoder status
276  * @param               pDLen           retrived length
277  *
278  * @return      res                     The index in type list
279  */
280 int
281 __VCardGetTypeName(char* pVCardRaw, int* pStatus, int* pDLen)
282 {
283         VDATA_TRACE_BEGINE
284         int     i, index, res;
285         char    c;
286         char    name[MAX_TYPE_NAME_LEN+1]={0,};
287
288 #ifdef VDATA_GROUPNAME_SUPPORTED
289         char*   szGroupName = NULL;
290 #endif // VDATA_GROUPNAME_SUPPORTED
291
292         SysRequireEx(pVCardRaw, UNKNOWN_NAME);
293
294         i = index = 0;
295         res = UNKNOWN_NAME;
296
297         while(true) {
298
299                 GO_NEXT_CHAR(c, pVCardRaw, pDLen);
300
301                 /**
302                  * TYPE NAME's length is must be less than MAX_TYPE_NAME_LEN.
303                  * If TYPE NAME's value is over MAX_TYPE_NAME_LEN, return UNKNOWN_NAME.
304                  * And then Decoding Step shoud not be changed.
305                  */
306                 if(index >= MAX_TYPE_NAME_LEN) {
307                         *pStatus = VCARD_TYPE_NAME_STATUS;
308                         res = UNKNOWN_NAME;
309                         break;
310                 }
311
312                 /**
313                  * There is a delimeter between TYPE NAME and next element(=Param, or Type Value).
314                  * If VTYPE_TOKEN_SEMICOLON or VTYPE_TOKEN_COLON is faced with,
315                  * find TYPE NAME's value in pszCardTypeList, and then return searched result.
316                  */
317                 if ((c == VTYPE_TOKEN_SEMICOLON ) || ( c == VTYPE_TOKEN_COLON)) {
318                         name[index] = 0x00;
319                         TRIM(name);
320                         UPPER(name,i,index);
321                         res = __VCardGetName( name, (char**)pszCardTypeList, VCARD_TYPE_NUM );
322                         break;
323                 }
324                 /** current version not support grouping vcard type */
325                 else if ( c == VTYPE_TOKEN_DOT ) {
326 #ifdef VDATA_GROUPNAME_SUPPORTED
327                         name[index] = '\0';
328                         szGroupName = ( char* ) malloc ( index+1 );
329                         if(szGroupName != NULL){
330                                 strncpy( szGroupName, name, index );
331                                 gszGroupName = szGroupName;
332                         }
333                         index = 0;
334 #endif
335                 }
336                 /**
337                  * There is no new line in TYPE NAME.
338                  * If new line character is faced with, return UNKNOWN_NAME;
339                  */
340                 else if ( ( c == '\r' ) || ( c == '\n' ) )
341                 {
342                         (*pDLen)++;
343                         *pStatus = VCARD_TYPE_NAME_STATUS;
344                         res = UNKNOWN_NAME;
345                         return res;
346                 }
347                 else if(_VIsSpace(c));
348                 else    name[index++] = c;
349         }
350
351         /**
352          *      Set Next Step.
353          *
354          */
355         if ( c == VTYPE_TOKEN_SEMICOLON )
356                 /**
357                  * This case next token is parameter. So set VCARD_PARAM_NAME_STATUS step.
358                  */
359                 *pStatus = VCARD_PARAM_NAME_STATUS;
360         else {
361                 if(res != UNKNOWN_NAME)
362                         /**
363                          * This case next string is value. So set VCARD_TYPE_VALUE_STATUS step.
364                          */
365                         *pStatus = VCARD_TYPE_VALUE_STATUS;
366                 else
367                         /**
368                          * In current step, TYPE NAME is invalid. So Try to get TYPE NAME again from next position.
369                          */
370                         *pStatus = VCARD_TYPE_NAME_STATUS;
371         }
372         VDATA_TRACE_END
373         return res;
374 }
375
376 /**
377  * __VCardGetParamName() fine the param name and returns the index number
378  *
379  * @param               pVCardRaw       The raw data
380  * @param               pStatus         Decoder status
381  * @param               pDLen           retrived length
382  *
383  * @return      res                     The index in type list
384  */
385 int
386 __VCardGetParamName( char* pVCardRaw, int* pStatus, int* pDLen )
387 {
388         VDATA_TRACE_BEGINE
389         int     i, index, res;
390
391         char    c;
392         char    name[MAX_PARAM_NAME_LEN+1]={0,};
393         char* pTemp = pVCardRaw;
394
395         SysRequireEx( pVCardRaw, UNKNOWN_NAME );
396
397         i = index = 0;
398         res = UNKNOWN_NAME;
399
400         while ( true )
401         {
402                 GO_NEXT_CHAR(c, pVCardRaw, pDLen);
403
404                 /**
405                  * PARAM NAME's length is must be less than MAX_PARAM_NAME_LEN.
406                  * If PARAM NAME's value is over MAX_PARAM_NAME_LEN, return UNKNOWN_NAME.
407                  * And then Decoding Step shoud not be changed.
408                  */
409                 if(index >= MAX_PARAM_NAME_LEN) {
410                         *pStatus = VCARD_TYPE_NAME_STATUS;
411                         res = UNKNOWN_NAME;
412                         break;
413                 }
414
415                 /**
416                  * There is a delimeter between PARAM NAME and next element(=Param, or Param Value).
417                  * If VTYPE_TOKEN_EQUAL is faced with,
418                  * find PARAM NAME's value in pszCardParamList, and then return searched result.
419                  */
420                 if(c == VTYPE_TOKEN_EQUAL) {
421                         name[index] = '\0';
422                         TRIM(name);
423                         UPPER(name, i, index);
424                         res = __VCardGetName( name, ( char** )pszCardParamList, VCARD_PARAM_NUM );
425                         if(res==UNKNOWN_NAME){
426                                 (*pDLen) = 0;
427                         }
428                         *pStatus = VCARD_PARAM_VALUE_STATUS;
429                         break;
430                 }
431                 /**
432                  * This case, There is no parameter type. Only Parameter Value.
433                  * In VCARD_PARAM_NAME_STATUS status, VTYPE_TOKEN_COLON means that anything parameter is no more.
434                  * so set next step to VCARD_PARAM_VALUE_STATUS.
435                  *
436                  * Ex) TEL;WORK:+12341234
437                  *        ------ ":" next is TEL TYPE's value.
438                  *
439                  * VCARD_PARAM_NAME_STATUS(current) -> VCARD_PARAM_VALUE_STATUS
440                  * -> VCARD_TYPE_VALUE_STATUS -> MOVE TO NEXT TYPE
441                  */
442                 else if(c == VTYPE_TOKEN_COLON) {
443                         *pStatus = VCARD_PARAM_VALUE_STATUS;
444                         pVCardRaw = pTemp;
445                         (*pDLen) = 0;
446                         res = UNKNOWN_NAME;
447                         break;
448                 }
449                 /**
450                  * This case, There is no parameter type. Only Parameter Value.
451                  * In VCARD_PARAM_NAME_STATUS status, VTYPE_TOKEN_SEMICOLON means that there is a next parameter.
452                  * so set next step to VCARD_PARAM_NAME_STATUS.
453                  *
454                  * Ex) TEL;WORK;PREF:+12341234
455                  *        ------ ":" next is TEL TYPE's value.
456                  *
457                  * VCARD_PARAM_NAME_STATUS(current) -> VCARD_PARAM_NAME_STATUS
458                  * -> VCARD_PARAM_VALUE_STATUS -> VCARD_TYPE_VALUE_STATUS -> MOVE TO NEXT TYPE
459                  */
460                 else if(c == VTYPE_TOKEN_SEMICOLON) {
461                         *pStatus = VCARD_PARAM_NAME_STATUS;
462                         pVCardRaw = pTemp;
463                         (*pDLen) = 0;
464                         res = UNKNOWN_NAME;
465                         break;
466                 }
467                 else if((c == '\r') || (c == '\n') || (_VIsSpace(c)));
468                 else
469                         name[index++] = c;
470         }
471         VDATA_TRACE_END
472         return res;
473 }
474
475 bool
476 __VCardFreeVTreeMemory(VTree * pTree)
477 {
478         VDATA_TRACE_BEGINE
479         VObject*                pCurObj = NULL;
480         VObject*                pNextObj = NULL;
481
482         VTree*                  pCurTree = NULL;
483         VTree*                  pNextTree = NULL;
484
485         VParam* pCurParam = NULL;
486         VParam* pNextParam = NULL;
487
488         int count = 0;
489         int i = 0;
490
491         SysRequireEx( pTree->treeType == VCARD, false );
492         SysRequireEx( pTree != NULL, false );
493         VDATA_TRACE("vcard_free_vtree_memory() entered.");
494
495         if (pTree->treeType != VCARD)
496         {
497                 VDATA_TRACE_END
498                 return true;
499         }
500
501         pCurTree = pTree;
502
503         while(pCurTree)
504         {
505                 pNextTree = pCurTree->pNext;
506                 pCurObj = pCurTree->pTop;
507
508                 while ( pCurObj )
509                 {
510
511                         pNextObj = pCurObj->pSibling;
512                         count = pCurObj->valueCount;
513
514                         for ( i = 0; i < count; i++ ) {
515                                 VFREE( pCurObj->pszValue[i]);
516                         }
517
518 #ifdef VDATA_GROUPNAME_SUPPORTED
519                         if ( pCurObj->pszGroupName )
520                                 VFREE( pCurObj->pszGroupName );
521 #endif
522
523                         if ( pCurObj->pParam )
524                         {
525
526                                 pCurParam = pCurObj->pParam;
527
528                                 while(pCurParam != NULL)
529                                 {
530                                         pNextParam = pCurParam->pNext;
531                                         VDATA_TRACE("pNEXT ==> %p", pCurParam->pNext);
532                                         VDATA_TRACE("pPARAM ==> %p", pCurParam->parameter);
533                                         VDATA_TRACE("pVALUE ==> %p", pCurParam->paramValue);
534                                         VDATA_TRACE("pCurParam : %p", pCurParam);
535                                         VDATA_TRACE("pCurParam->parameter : %d", pCurParam->parameter);
536                                         VDATA_TRACE("pCurParam->paramValue : %d", pCurParam->paramValue);
537                                         if(pNextParam != NULL) {
538                                                 VDATA_TRACE("pNextParam : %p", pNextParam);
539                                                 VDATA_TRACE("pNextParam->parameter : %d", pNextParam->parameter);
540                                                 VDATA_TRACE("pNextParam->paramValue : %d", pNextParam->paramValue);
541                                         }
542                                         VFREE(pCurParam);
543                                         pCurParam = pNextParam;
544                                 }
545                         }
546
547                         VFREE( pCurObj );
548                         pCurObj = pNextObj;
549                 }
550
551                 VFREE( pCurTree );
552                 pCurTree = pNextTree;
553         }
554
555         VDATA_TRACE("exit vcard_free_vtree_memory");
556         VDATA_TRACE_END
557         return true;
558 }
559
560 /**
561  * __VCardGetParamVal() fine the param value and returns value.
562  *
563  * @param               pVCardRaw       The raw data
564  * @param               pStatus         Decoder status
565  * @param               pDLen           retrived length
566  *
567  * @return      buffer          The result value
568  */
569 char*
570 __VCardGetParamVal( char* pVCardRaw, int* pStatus, int* pDLen )
571 {
572         VDATA_TRACE_BEGINE
573         int len = 0;
574         char    c;
575         char* pBuf = NULL;
576         char* pTemp = pVCardRaw;
577
578         SysRequireEx( pVCardRaw, NULL );
579
580         while(true) {
581                 GO_NEXT_CHAR(c, pVCardRaw, pDLen);
582                 len++;
583                 switch(c) {
584                         case VTYPE_TOKEN_SEMICOLON :
585                                 *pStatus = VCARD_PARAM_NAME_STATUS;
586                                 break;
587                         case VTYPE_TOKEN_COLON :
588                                 *pStatus = VCARD_TYPE_VALUE_STATUS;
589                                 break;
590                         case VTYPE_TOKEN_COMMA :
591                                 *pStatus = VCARD_PARAM_VALUE_STATUS;
592                                 break;
593                 }
594                 if( c == VTYPE_TOKEN_SEMICOLON
595                                 || c == VTYPE_TOKEN_COLON
596                                 || c == VTYPE_TOKEN_COMMA
597                                 || c == 0x00)
598                         break;
599         }
600
601         pBuf = (char *)malloc(len);
602         if(len < 1 || (pBuf  == NULL)) {
603                 if (pBuf) {
604                         free(pBuf);
605                         pBuf = NULL;
606                 }
607
608                 return NULL;
609         }
610         memset(pBuf, 0x00, len);
611         memcpy( pBuf, pTemp, len-1 );
612         TRIM(pBuf);
613         VDATA_TRACE_END
614         return pBuf;
615 }
616
617
618 /**
619  * __VCardGetTypeVal() fine the type value and returns value.
620  *
621  * @param       pVCardRaw       The raw data
622  * @param               status                  Decoder status
623  * @return      buffer          The result value
624  */
625 char*
626 __VCardGetTypeVal( char* pVCardRaw, int* pStatus, int* pDLen, int enc, VObject* pType)
627 {
628         VDATA_TRACE_BEGINE
629         int num = 0;
630         int len = 0;
631         int bufferCount = 0;
632
633         bool bEscape = false;
634
635         char    c, c1, c2;
636         char* pBuf = NULL;
637         char* pTemp = pVCardRaw;
638         char* pTmpBuf = NULL;
639         int Status = 0;
640         int Len = 0;
641
642         SysRequireEx( pVCardRaw, NULL );
643
644         while(true)
645         {
646                 GO_NEXT_CHAR(c, pVCardRaw, pDLen);
647
648                 if( c == 0x00) break;
649
650                 len++;
651
652                 /** This case means that there are more type's value. */
653                 if ( c == VTYPE_TOKEN_SEMICOLON && bEscape == false ) {
654
655                         if((pBuf = (char *)malloc(len)) == NULL) return NULL;
656
657                         memset(pBuf, 0x00, len);
658                         memcpy(pBuf,pTemp,len-1);
659
660                         TRIM(pBuf);
661                         _VUnescape(pBuf);
662
663                         *pStatus = VCARD_TYPE_VALUE_STATUS;
664
665                         /** Base 64 Decoding */
666                         if((enc & pEncList[1].flag) || (enc & pEncList[0].flag)) {
667
668                                 bufferCount = (len * 6 / 8) + 2;
669
670                                 if((pTmpBuf = (char *)malloc(bufferCount)) == NULL) {
671                                         VFREE(pBuf);
672                                         return NULL;
673                                 }
674
675                                 memset(pTmpBuf, 0x00, bufferCount);
676                                 num = _VB64Decode(pTmpBuf, pBuf);
677
678                                 if(pType != NULL) pType->numOfBiData = num;
679
680                                 VFREE(pBuf);
681                                 pBuf = pTmpBuf;
682                                 pTmpBuf = NULL;
683                                 break;
684                         }
685
686                         /** Quoted Printable Decoding */
687                         if(enc & pEncList[2].flag) {
688
689                                 int i = 0, j = 0;
690
691                                 while(pBuf[i]) {
692                                         if(pBuf[i] == '\n' || pBuf[i] == '\r'){
693                                                 i++;
694                                                 if(pBuf[i] == '\n'|| pBuf[i] == '\r')
695                                                         i++;
696
697                                                 if(pBuf[j-1] == '=') j--;
698                                         }
699                                         else
700                                                 pBuf[j++] = pBuf[i++];
701                                 }
702                                 pBuf[j] = '\0';
703
704                                 _VQPDecode(pBuf);
705                                 TRIM(pBuf);
706                                 break;
707                         }
708                         break;
709                 }
710
711                 if(c == '\\')
712                         bEscape = true;
713                 else if(bEscape == true && c != VTYPE_TOKEN_SEMICOLON )
714                         bEscape = false;
715                 else if((c == '\r') || (c == '\n'))
716                 {
717                         c2 = *(pVCardRaw-2);
718
719                         if(c2 == '=' && (enc & pEncList[2].flag))
720                         {
721                                 c1 = *pVCardRaw;
722                                 if((c1 == '\r') || (c1 == '\n'))
723                                 {
724                                         pVCardRaw += 1;
725                                         (*pDLen) += 1;
726                                         len++;
727                                 }
728                         }
729                         else if(__VCardGetTypeName(pVCardRaw, &Status, &Len) != UNKNOWN_NAME)
730                         {
731                                 --len;
732                                 if((pBuf = (char *)malloc(len)) == NULL) return NULL;
733
734                                 memset(pBuf, 0x00, len);
735                                 memcpy(pBuf,pTemp,len-1);
736
737                                 TRIM(pBuf);
738                                 _VUnescape(pBuf);
739
740                                 *pStatus = VCARD_TYPE_NAME_STATUS;
741
742                                 c1 = *pVCardRaw;
743
744                                 if((c1 == '\r') || (c1 == '\n')) {
745                                         pVCardRaw += 1;
746                                         (*pDLen) += 1;
747                                 }
748
749                                 if((enc & pEncList[1].flag) || (enc & pEncList[0].flag)) {
750
751                                         bufferCount = (len * 6 / 8) + 5;
752
753                                         if((pTmpBuf = (char *)malloc(bufferCount)) == NULL) {
754                                                 VFREE(pBuf);
755                                                 return NULL;
756                                         }
757
758                                         memset(pTmpBuf, 0x00, bufferCount);
759                                         num = _VB64Decode(pTmpBuf, pBuf);
760
761                                         if(pType != NULL)
762                                                 pType->numOfBiData = num;
763
764                                         VFREE(pBuf);
765                                         pBuf = pTmpBuf;
766                                         pTmpBuf = NULL;
767                                         break;
768                                 }
769
770                                 if(enc & pEncList[2].flag) {
771
772                                         int i = 0, j = 0;
773
774                                         while(pBuf[i])
775                                         {
776                                                 if(pBuf[i] == '\n' || pBuf[i] == '\r')
777                                                 {
778                                                         i++;
779                                                         if(pBuf[i] == '\n' || pBuf[i] == '\r')
780                                                                 i++;
781
782                                                         if(pBuf[j-1] == '=') j--;
783                                                 }
784                                                 else
785                                                         pBuf[j++] = pBuf[i++];
786                                         }
787                                         pBuf[j] = '\0';
788
789                                         _VQPDecode(pBuf);
790                                         TRIM(pBuf);
791                                         break;
792                                 }
793                                 break;
794                         }
795                 }
796         }
797         VDATA_TRACE_END
798         return pBuf;
799 }
800
801
802 int
803 VCardGetTypeValue( int index )
804 {
805         VDATA_TRACE_BEGINE
806         VDATA_TRACE("VCardGetTypeValue() enter..\n");
807         VDATA_TRACE_END
808         return pTypeList[index].flag;
809 }
810
811 int
812 VCardGetValValue( int index )
813 {
814         VDATA_TRACE_BEGINE
815         VDATA_TRACE("VCardGetValValue() enter..\n");
816         VDATA_TRACE_END
817         return pValueList[index].flag;
818 }
819
820 int
821 VCardGetEncValue( int index )
822 {
823         VDATA_TRACE_BEGINE
824         VDATA_TRACE("VCardGetEncValue() enter..\n");
825         VDATA_TRACE_END
826         return pEncList[index].flag;
827 }
828
829 int
830 VCardGetCharsetValue( int index )
831 {
832         VDATA_TRACE_BEGINE
833         VDATA_TRACE("VCardGetCharsetValue() enter..\n");
834         VDATA_TRACE_END
835         return pCharsetList[index].flag;
836 }
837
838 /*
839  * vcard_decode() decode the vCard data and returns vObject struct
840  *
841  * @param       pVCardRaw            The raw data
842  * @return      vObject             The result value
843  */
844 SLPAPI VTree*
845 vcard_decode( char *pCardRaw )
846 {
847         VDATA_TRACE_BEGINE;
848         char* szValue = NULL;
849         char* szCardBegin = NULL;
850         char* pCardRawTmp = NULL;
851         VTree* pVCard = NULL;
852         VParam* pTmpParam = NULL;
853         VObject* pTemp = NULL;
854
855         char    c;
856
857         int type, param;
858         int status = VCARD_TYPE_NAME_STATUS;
859         int done = false;
860         int valueCount = 0;
861         int len;
862         int dLen = 0;
863         int param_status = false;
864         int numberedParam = 0;
865         int enc = 0;
866         int start_status = 0;
867         char* temp = NULL;
868
869         bool vcard_ended = false;
870
871         SysRequireEx(pCardRaw != NULL, NULL);
872         len = strlen(pCardRaw);
873
874         pCardRaw = _VUnfoldingNoSpecNew(pCardRaw);
875         pCardRawTmp = pCardRaw;
876         len = _VManySpace2Space( pCardRaw );
877
878         if(!__VIsVcardFile(pCardRaw, CHECK_START)) {
879                 VFREE(pCardRawTmp);
880                 VDATA_TRACE_END
881                 return NULL;
882         }
883
884
885         while(true && !done)
886         {
887                 c = *pCardRaw;
888
889                 if((c == '\0') || done)
890                         break;
891
892                 switch(status) {
893                         case VCARD_TYPE_NAME_STATUS:
894                                 dLen = 0;
895                                 type = __VCardGetTypeName(pCardRaw, &status, &dLen);
896                                 pCardRaw += dLen;
897
898                                 if(type == -1)
899                                         break;
900
901                                 switch ( type )
902                                 {
903                                         case VCARD_TYPE_BEGIN:
904                                                 if(start_status == 1) {
905                                                         goto CATCH;
906                                                 }
907                                                 if ( ( pVCard = ( VTree* )malloc( sizeof( VTree ) ) ) == NULL ) {
908                                                         start_status = 1;
909                                                         goto CATCH;
910                                                 }
911
912                                                 memset(pVCard,0x00, sizeof(VTree));
913
914                                                 dLen = 0;
915                                                 szCardBegin = __VCardGetTypeVal(pCardRaw, &status, &dLen, enc, NULL);
916                                                 pCardRaw += dLen;
917                                                 VFREE(szCardBegin);
918
919                                                 pVCard->treeType = VCARD;
920                                                 pVCard->pTop = NULL;
921                                                 pVCard->pCur = NULL;
922                                                 pVCard->pNext = NULL;
923                                                 break;
924
925                                         case VCARD_TYPE_END:
926                                                 enc = 0;
927                                                 if(strstr(pCardRaw,"VCARD") != NULL) {
928                                                         pCardRaw += dLen;
929                                                         done = true;
930                                                 vcard_ended = true;
931                                                 }
932                                                 else    {
933                                                         status = VCARD_TYPE_NAME_STATUS;
934                                                         pCardRaw += dLen;
935                                                         //VFREE(etemp);
936                                                 }
937                                                 break;
938
939                                         case UNKNOWN_NAME :
940                                                 break;
941
942                                         default:
943                                                 if(UNKNOWN_NAME == type || type < 0) {
944                                                         status = VCARD_TYPE_NAME_STATUS;
945                                                         break;
946                                                 }
947
948                                                 if ( ( pTemp = ( VObject* )malloc( sizeof( VObject ) ) ) == NULL ) {
949                                                         goto CATCH;
950                                                 }
951
952                                                 memset( pTemp, 0, sizeof( VObject ) );
953                                                 pTemp->property = type;
954
955                                                 if ( pVCard->pTop == NULL ) {
956                                                         pVCard->pTop = pTemp;
957                                                         pVCard->pCur = pTemp;
958                                                 }
959                                                 else {
960                                                         pVCard->pCur->pSibling = pTemp;
961                                                         pVCard->pCur = pTemp;
962                                                 }
963
964                                                 break;
965                                 }
966
967                                 numberedParam = 0;
968                                 param_status = false;
969                                 valueCount = 0;
970
971 #ifdef VDATA_GROUPNAME_SUPPORTED
972                                 if ( gszGroupName != NULL )
973                                         pVCard->pCur->pszGroupName = gszGroupName;
974 #endif
975                                 break;
976
977                         case VCARD_PARAM_NAME_STATUS:
978                         {
979                                 dLen = 0;
980                                 param = __VCardGetParamName( pCardRaw, &status, &dLen );
981                                 pCardRaw += dLen;
982
983                                 if ( param_status != true ) {
984
985                                         if ( ( pTmpParam = ( VParam* )malloc( sizeof( VParam ) ) ) == NULL )
986                                                         goto CATCH;
987
988                                         param_status = true;
989                                         pVCard->pCur->pParam = pTmpParam;
990                                         memset( pTmpParam, 0x00, sizeof( VParam ) );
991                                         VDATA_TRACE("pTmpParam : %p", pTmpParam);
992                                 }
993                                 else
994                                 {
995                                         if ( ( pTmpParam->pNext = ( VParam* )malloc( sizeof( VParam ) ) ) == NULL )
996                                                         goto CATCH;
997
998                                         pTmpParam = pTmpParam->pNext;
999                                         memset( pTmpParam, 0x00, sizeof(VParam));
1000                                         VDATA_TRACE("pTmpParam : %p", pTmpParam);
1001                                 }
1002
1003                                 pTmpParam->parameter = param;
1004                                 break;
1005                         }
1006                         case VCARD_PARAM_VALUE_STATUS:
1007                                 dLen = 0;
1008                                 numberedParam = 0;
1009                                 switch ( pTmpParam->parameter )
1010                                 {
1011                                         case VCARD_PARAM_TYPE:
1012                                                 szValue = __VCardGetParamVal( pCardRaw, &status, &dLen );
1013                                                 numberedParam |= __VCardGetValue( szValue, pTypeList, VCARD_TYPE_PARAM_NUM );
1014                                                 break;
1015                                         case VCARD_PARAM_VALUE:
1016                                                 szValue = __VCardGetParamVal( pCardRaw, &status, &dLen );
1017                                                 numberedParam |= __VCardGetValue( szValue, pValueList, VCARD_VALUE_PARAM_NUM );
1018                                                 break;
1019                                         case VCARD_PARAM_ENCODING:
1020                                                 szValue = __VCardGetParamVal( pCardRaw, &status, &dLen );
1021                                                 numberedParam |= __VCardGetValue( szValue, pEncList, VCARD_ENCODE_PARAM_NUM );
1022                                                 enc = numberedParam;
1023                                                 break;
1024                                         case VCARD_PARAM_CHARSET:
1025                                                 szValue = __VCardGetParamVal( pCardRaw, &status, &dLen );
1026                                                 numberedParam |= __VCardGetValue( szValue, pCharsetList, VCARD_CHARSET_PARAM_NUM );
1027                                                 break;
1028                                         case VCARD_PARAM_CONTEXT:
1029                                         case VCARD_PARAM_LANGUAGE:
1030                                                 // prevent 7605 08.03.13
1031                                                 szValue = __VCardGetParamVal( pCardRaw, &status, &dLen );
1032                                                 numberedParam = 0;
1033                                                 break;
1034                                         default:
1035                                                 szValue = __VCardGetParamVal( pCardRaw, &status, &dLen );
1036
1037                                                 SET_PARAM_VALUE(numberedParam, szValue, pTypeList, VCARD_TYPE_PARAM_NUM, pTmpParam, VCARD_PARAM_TYPE, enc);
1038                                                 SET_PARAM_VALUE(numberedParam, szValue, pValueList, VCARD_VALUE_PARAM_NUM, pTmpParam, VCARD_PARAM_VALUE, enc);
1039                                                 SET_PARAM_VALUE(numberedParam, szValue, pEncList, VCARD_ENCODE_PARAM_NUM, pTmpParam, VCARD_PARAM_ENCODING, enc);
1040                                                 SET_PARAM_VALUE(numberedParam, szValue, pCharsetList, VCARD_CHARSET_PARAM_NUM, pTmpParam, VCARD_PARAM_CHARSET, enc);
1041
1042                                                 numberedParam = 0;
1043                                                 pCardRaw += dLen;
1044                                                 dLen = 0;
1045
1046                                                 break;
1047                                 }
1048
1049                                 VDATA_TRACE("%d, %s, %p",numberedParam, szValue, pTmpParam);
1050                                 pTmpParam->paramValue = numberedParam;
1051                                 pTmpParam->pNext = NULL;
1052                                 VFREE(szValue);
1053                                 pCardRaw += dLen;
1054                                 break;
1055                         case VCARD_TYPE_VALUE_STATUS:
1056                                 dLen = 0;
1057                                 temp = __VCardGetTypeVal( pCardRaw, &status, &dLen, enc, pVCard->pCur);
1058
1059                                 if(valueCount <= VDATA_VALUE_COUNT_MAX) {
1060                                         pVCard->pCur->pszValue[valueCount] = temp;
1061                                         valueCount++;
1062                                         pVCard->pCur->valueCount = valueCount;
1063                                 }
1064                                 else
1065                                         VFREE(temp);
1066
1067                                 pCardRaw += dLen;
1068                                 break;
1069                 }
1070         }
1071
1072         VFREE(pCardRawTmp);
1073
1074         if(pVCard->pTop == NULL)
1075                 goto CATCH;
1076
1077         if(!vcard_ended) {
1078                 goto CATCH1;
1079         }
1080         VDATA_TRACE_END
1081         return pVCard;
1082
1083 CATCH :
1084         VFREE(pTemp);
1085 CATCH1 :
1086         VFREE(pCardRawTmp);
1087         __VCardFreeVTreeMemory(pVCard);
1088         VDATA_TRACE_END
1089         return NULL;
1090 }
1091
1092 /*
1093  * vcard_encode() compares the string and vCard type, parameter value.
1094  *
1095  * @param       pVCardRaw            Data which will be encoded
1096  * @return      char *              Encoded result
1097  */
1098 SLPAPI char*
1099 vcard_encode( VTree *pVCardRaw )
1100 {
1101         VDATA_TRACE_BEGINE
1102         char*           pVCardRes = NULL;
1103         VObject *       pTmpObj =  NULL;
1104         char*           pTemp = NULL;
1105         int                     len;
1106         int                     total = 0;
1107         int             cnt = 0;
1108         int             lenTypeList = 0;
1109
1110         LENGTH_TYPE_LIST(pszCardTypeList, lenTypeList);
1111
1112         SysRequireEx(pVCardRaw != NULL, NULL);
1113         SysRequireEx(pVCardRaw->pTop != NULL, NULL);
1114         SysRequireEx(pVCardRaw->pTop->property >= 0, NULL);
1115         SysRequireEx(pVCardRaw->pTop->property < lenTypeList, NULL);
1116         SysRequireEx(pVCardRaw->treeType == VCARD, NULL);
1117         SysRequireEx(pVCardRaw->pTop->valueCount > 0, NULL);
1118
1119         //VDATA_TRACE("START %d %d", pVCardRaw->pTop->property, lenTypeList);
1120
1121         for(;cnt < pVCardRaw->pTop->valueCount;cnt++) {
1122
1123                 if(pVCardRaw->pTop->pszValue[cnt] == NULL)  {
1124                         VDATA_TRACE("pVCardRaw->pTop->valueCount : %d",pVCardRaw->pTop->valueCount);
1125                         VDATA_TRACE("pVCardRaw->pTop->pszValue[%d] : %s", cnt, pVCardRaw->pTop->pszValue[cnt]);
1126                         VDATA_TRACE_END
1127                         return NULL;
1128                 }
1129         }
1130
1131         if ( ( pVCardRes = ( char * )malloc( sizeof( char ) * ( total += 14 + 14 ) ) ) == NULL )
1132         {
1133                 VDATA_TRACE(  "vcard_encode:malloc failed\n" );
1134                 VDATA_TRACE_END
1135                 return NULL;
1136         }
1137
1138         memcpy( pVCardRes, "BEGIN:VCARD\r\n", 14 );
1139         strcat( pVCardRes, "VERSION:2.1\r\n" );
1140
1141         pTmpObj = pVCardRaw->pTop;
1142
1143         while ( true )
1144         {
1145                 if(pTmpObj == NULL)
1146                         break;
1147
1148                 if ( ( pTemp = __VCardTypeEncode( pTmpObj, pszCardTypeList[pTmpObj->property] ) ) != NULL )
1149                 {
1150                         len = strlen( pTemp );
1151
1152                         if ( ( pVCardRes = ( char* )realloc( pVCardRes, ( total += len+10 ) ) ) == NULL )
1153                         {
1154                                 VDATA_TRACE(  "vcard_encode():realloc failed\n");
1155                                 VFREE( pTemp );
1156                                 pTemp = NULL;
1157                                 VDATA_TRACE_END
1158                                 return NULL;
1159                         }
1160
1161                         if( strncmp(pTemp,"VERSION", strlen("VERSION")) != 0)
1162                                 strncat(pVCardRes, pTemp, strlen(pTemp));
1163
1164                         VDATA_TRACE("pTemp : %s", pTemp);
1165
1166                         VFREE( pTemp );
1167                         pTemp = NULL;
1168                 }
1169
1170                 if ( pTmpObj->pSibling != NULL )
1171                         pTmpObj = pTmpObj->pSibling;
1172                 else
1173                         break;
1174         }
1175
1176         if ( ( pVCardRes = ( char * )realloc( pVCardRes, ( total += 12 ) ) ) == NULL )
1177         {
1178                 VDATA_TRACE(  "vcard_encode:realloc failed\n");
1179                 VDATA_TRACE_END
1180                 return NULL;
1181         }
1182         strcat( pVCardRes, "END:VCARD\r\n" );
1183         VDATA_TRACE_END
1184         return pVCardRes;
1185 }
1186
1187
1188 /*
1189  * VIsVcardFile() verify VCard file.
1190  *
1191  * @param       pVCardRaw           Data which will be encoded
1192  * @return      int                 result (true or false)
1193  */
1194 int
1195 __VIsVcardFile(char *pCardRaw, int mode)
1196 {
1197         int i=0;
1198         bool rtnValue = true;
1199         char *pszVcardBegin = "BEGIN:VCARD";
1200
1201         switch(mode)
1202         {
1203                 case CHECK_START :
1204                         for(i=0; i < 11; i++)
1205                 if(*pszVcardBegin++ != *pCardRaw++)
1206                                         rtnValue = false;
1207                         break;
1208
1209                 default :
1210                         rtnValue = false;
1211         }
1212         VDATA_TRACE_END
1213         return rtnValue;
1214 }
1215
1216
1217 /*
1218  * vCardTypeEncoder() compares the string and vCard type, parameter value.
1219  *
1220  * @param               typeObj                         Data which will be encoded
1221  * @param               type                            Name of the type
1222  * @return      char *              Encoded result
1223  */
1224 char*
1225 __VCardTypeEncode( VObject *pTypeObj, char *pType )
1226 {
1227         VDATA_TRACE_BEGINE
1228         int                     len;
1229         char*           pTemp = NULL;
1230         char*           szTypeValue = NULL;
1231         int                     i;
1232         int                     enc = 0;
1233         char*           pEncode = NULL;
1234         char*           pRes = NULL;
1235         int                     total = 0;
1236         int                     biLen = 0;
1237
1238         len = strlen( pType );
1239         biLen = pTypeObj->numOfBiData;
1240
1241 #ifdef VDATA_GROUPNAME_SUPPORTED
1242         if ( pTypeObj->pszGroupName != NULL )
1243         {
1244                 len += strlen( pTypeObj->pszGroupName ) + 1;
1245         }
1246 #endif // VDATA_GROUPNAME_SUPPORTED
1247         if ( ( szTypeValue = ( char * )malloc( total += ( len+1 ) ) ) == NULL )
1248         {
1249                 VDATA_TRACE(  "__VCardTypeEncode():malloc failed\n");
1250                 VDATA_TRACE_END
1251                 return NULL;
1252         }
1253         memset( szTypeValue, '\0', ( len+1 ) );
1254 #ifdef VDATA_GROUPNAME_SUPPORTED
1255         if ( pTypeObj->pszGroupName != NULL )
1256         {
1257                 strcat( szTypeValue, pTypeObj->pszGroupName );
1258                 strcat( szTypeValue, "." );
1259         }
1260 #endif // VDATA_GROUPNAME_SUPPORTED
1261         strcat( szTypeValue, pType );
1262
1263         pTemp = __VCardParamEncode( pTypeObj, &enc );
1264         if ( pTemp != NULL )
1265         {
1266                 len = strlen( pTemp );
1267                 if ( ( szTypeValue = ( char * )realloc( szTypeValue, ( total += len ) ) ) == NULL )
1268                 {
1269                         VDATA_TRACE(  "__VCardTypeEncode():realloc failed\n");
1270                         VFREE( pTemp );
1271                         pTemp = NULL
1272                         VDATA_TRACE_END;
1273                         return NULL;
1274                 }
1275                 strcat( szTypeValue, pTemp );
1276                 VFREE( pTemp );
1277                 pTemp = NULL;
1278         }
1279
1280         if ( ( szTypeValue = ( char * )realloc( szTypeValue, ( total += 2 ) ) ) == NULL )
1281         {
1282                 VDATA_TRACE_END
1283                 return NULL;
1284         }
1285
1286         strcat( szTypeValue, ":" );
1287
1288         len = 0;
1289
1290         if(strcmp(pType, pszCardTypeList[19]) != 0)     {
1291                 for ( i = 0; i < pTypeObj->valueCount; i++ ) {
1292
1293                         if(pTypeObj->pszValue[i] != NULL)
1294                         len += strlen( pTypeObj->pszValue[i] );
1295                 }
1296         }
1297         else {
1298                 len += biLen;
1299         }
1300
1301         for ( i = 0; i < pTypeObj->valueCount; i++ ) {
1302
1303                 if ( i == 0 ) {
1304                         if ( ( pEncode = ( char * )malloc( len+20 ) ) == NULL ) {
1305                                 VFREE(szTypeValue);
1306                                 VDATA_TRACE_END
1307                                 return NULL;
1308                         }
1309
1310                         memset( pEncode, '\0', len+20 );
1311
1312                         if(strcmp(pType, pszCardTypeList[19]) != 0)     {
1313                                 strcat( pEncode, pTypeObj->pszValue[i] );
1314                                 _VEscape(pEncode);
1315                         }
1316                         else
1317                                 memcpy(pEncode, pTypeObj->pszValue[i], biLen);
1318                         }
1319                 else {
1320                         char    buf[1000];
1321                         strncpy( buf, pTypeObj->pszValue[i], 999 );
1322                         _VEscape( buf );
1323                         strcat( pEncode, ";" );
1324                         strcat( pEncode, buf );
1325                 }
1326         }
1327
1328         if(strcmp(pType, pszCardTypeList[19]) != 0)     {
1329                 if (pEncode) {
1330                         strcat( pEncode, "\0\0" );
1331                         len = strlen( pEncode );
1332                 }
1333         }
1334         else {
1335                 len = biLen;
1336         }
1337
1338         if ( enc & pEncList[2].flag ) {
1339                 if((pRes = (char *)malloc(len * 6 + 10)) == NULL) {
1340                         VFREE(pEncode);
1341                         VFREE(szTypeValue);
1342                         VDATA_TRACE_END
1343                         return NULL;
1344                 }
1345                 if(pEncode)
1346                         _VQPEncode( pRes, pEncode );
1347                 VFREE(pEncode);
1348                         }
1349         else if(enc & pEncList[1].flag ) {
1350                 if((pRes = (char *)malloc((len * 8 / 6) + 4)) == NULL){
1351                         VFREE(pEncode);
1352                         VFREE(szTypeValue);
1353                         VDATA_TRACE_END
1354                         return NULL;
1355                 }
1356
1357                 memset( pRes, '\0', ( ( len * 8 / 6 ) + 4 ) );
1358                 _VB64Encode( pRes, pEncode, biLen );
1359                 VFREE(pEncode);
1360                         }
1361         else {
1362                 if((pRes = (char *)malloc(len+30)) == NULL) {
1363                         VFREE(pEncode);
1364                         VFREE(szTypeValue);
1365                         VDATA_TRACE_END
1366                         return NULL;
1367                 }
1368                 memset( pRes, '\0', ( len + 30 ) );
1369                 if(pEncode)
1370                 {
1371                         memcpy( pRes, pEncode, len );
1372                         VFREE(pEncode);
1373                 }
1374         }
1375
1376         if((pRes = (char *)realloc(pRes, strlen(pRes) + 3)) == NULL)
1377         {
1378                 VFREE(pEncode);
1379                 VFREE(szTypeValue);
1380                 VDATA_TRACE_END
1381                 return NULL;
1382         }
1383         strncat( pRes, "\r\n", strlen(pRes) + 2);
1384
1385         len = strlen( pRes );
1386
1387         if ((szTypeValue = (char *)realloc(szTypeValue, (total += (len+3)))) == NULL) {
1388                 VFREE(pEncode);
1389                 VFREE(pRes);
1390                 VDATA_TRACE_END
1391                 return NULL;
1392         }
1393
1394         strncat(szTypeValue, pRes, total - 1);
1395
1396         if(strcmp(pType, pszCardTypeList[19]) != 0) {
1397                 _VRLSpace( szTypeValue );
1398                 _VRTSpace( szTypeValue );
1399         }
1400
1401         VFREE(pRes);
1402         VDATA_TRACE_END
1403         return szTypeValue;
1404 }
1405
1406 /**
1407  * __VCardParamEncode() Parameter Encoding.
1408  *
1409  * @param               pTypeObj                Data which will be encoded
1410  * @param               pEnc                            Name of the type
1411  */
1412 char *
1413 __VCardParamEncode(VObject* pTypeObj, int* pEnc)
1414 {
1415         VDATA_TRACE_BEGINE
1416         int i = 0;
1417         int len = 0;
1418         int sNum = 0;
1419         int shift = 0;
1420         bool bSupported;
1421         char* szParam = NULL;
1422         VParam* pTemp = NULL;
1423         ValueObj*       pList = NULL;
1424
1425         /** Paramter initialize. */
1426         pTemp = pTypeObj->pParam;
1427
1428         /** Momory Allocation for parameter string. */
1429         if(pTemp != NULL) {
1430                 if ((szParam = (char*)malloc(len+=2)) == NULL)
1431                 {
1432                         VDATA_TRACE_END
1433                         return NULL;
1434                 }
1435                 memset(szParam, 0x00, 2);
1436         }
1437
1438         /** appending pamaters. */
1439         while(true) {
1440
1441                 if(pTemp == NULL) break;
1442
1443                 bSupported = false;
1444
1445                 /** Expand szParam string. For appending.*/
1446                 if((szParam = (char *)realloc(szParam, len += 15)) == NULL)
1447                 {
1448                         VDATA_TRACE_END
1449                         return NULL;
1450                 }
1451
1452                 /** appending paramter name. */
1453                 strcat( szParam, ";" );
1454                 if(pTemp->parameter != VCARD_PARAM_TYPE) {
1455                         strcat( szParam, pszCardParamList[pTemp->parameter] );
1456                         strcat( szParam, "=" );
1457                 }
1458
1459                 /** Set Parameter Value name. */
1460                 switch ( pTemp->parameter )
1461                 {
1462                         case VCARD_PARAM_ENCODING:
1463                                 *pEnc = pTemp->paramValue;
1464                                 shift = VCARD_ENCODE_PARAM_NUM;
1465                                 pList = pEncList; bSupported = true;
1466                                 break;
1467                         case VCARD_PARAM_TYPE:
1468                                 shift = VCARD_TYPE_PARAM_NUM;
1469                                 pList = pTypeList; bSupported = true;
1470                                 break;
1471                         case VCARD_PARAM_VALUE:
1472                                 shift = VCARD_VALUE_PARAM_NUM;
1473                                 pList = pValueList; bSupported = true;
1474                                 break;
1475                         case VCARD_PARAM_CHARSET:
1476                                 shift = VCARD_CHARSET_PARAM_NUM;
1477                                 pList = pCharsetList; bSupported = true;
1478                                 break;
1479                         default:
1480                                 if ( ( szParam = ( char* )realloc( szParam, 5 ) ) == NULL )
1481                                 {
1482                                         VDATA_TRACE_END
1483                                         return NULL;
1484                                 }
1485                                 strcat( szParam, "NONE" );
1486                 }
1487
1488                 /** exchage parameter value's to string.*/
1489                 if(bSupported == true) {
1490
1491                         for(i = 0, sNum = 0x00000001; i < shift; i++) {
1492
1493                                 if(pTemp->paramValue & sNum) {
1494                                         if((szParam = (char *)realloc(szParam, ( len += (strlen(pList[i].szName) + 2)))) == NULL)
1495                                         {
1496                                                 VDATA_TRACE_END
1497                                                 return NULL;
1498                                         }
1499
1500                                         strcat( szParam, pList[i].szName );
1501                                         strcat( szParam, "; " );
1502                                 }
1503
1504                                 sNum <<= 1;
1505                         }
1506                 }
1507
1508                 /** remove semicolon from tail. */
1509                 for(i = strlen( szParam ); i > 0 ; i--) {
1510
1511                         if ( szParam[i] == ' ' && szParam[i-1] == ';' ) {
1512                                 szParam[i-1] = '\0';
1513                                 break;
1514                         }
1515                 }
1516
1517                 if ( pTemp->pNext != NULL )
1518                         pTemp = pTemp->pNext;
1519                 else
1520                         break;
1521         }
1522         VDATA_TRACE_END
1523         return szParam;
1524 }
1525
1526 SLPAPI bool
1527 vcard_free_vtree_memory(VTree * pTree)
1528 {
1529         VDATA_TRACE_BEGINE
1530         if(pTree == NULL)
1531         {
1532                 VDATA_TRACE_END
1533                 return false;
1534         }
1535         VDATA_TRACE_END
1536         return __VCardFreeVTreeMemory(pTree);
1537 }
1538