2 * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
4 * Licensed under the Apache License, Version 2.0 (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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #define MAX_TYPE_NAME_LEN 50
23 #define MAX_PARAM_NAME_LEN 50
27 #define VFREE(obj) if (obj != NULL) { /*VDATA_TRACE("%p",obj);*/ free(obj); \
31 #define TRIM(obj) if (obj != NULL) {\
36 #define UPPER(obj, start, end) if (obj != NULL) {\
37 for (start = 0; start < end; start++)\
38 obj[start] = toupper(obj[start]);\
41 #define GO_NEXT_CHAR(current, rowData, addedCnt) {\
47 #define SET_PARAM_VALUE(PARAM, SZVALUE, LIST, LISTCNT, PARAMOBJ, PTYPE, ENC) {\
49 PARAM |= __VMsgGetValue(SZVALUE, LIST, LISTCNT);\
50 if (PARAM != UNKNOWN_NAME) {\
51 PARAMOBJ->parameter = PTYPE;\
52 if (PTYPE == VMSG_PARAM_ENCODING)\
58 #define LENGTH_TYPE_LIST(obj, len) for (len = 0; obj[len] != NULL; len++);
60 extern char* _VUnfoldingNoSpecNew(char *string);
62 /** GLOBAL VARIABLE DECLARATION AND INITIALIZATION */
64 char* pszMsgTypeList[] = {
80 char* pszMsgParamList[] = {
90 ValueObj pMsgEncList[] = {
92 {"BASE64", 0x00000002},
93 {"QUOTED-PRINTABLE", 0x00000004},
98 /** Character set value */
99 ValueObj pMsgCharsetList[] = {
100 {"UTF-8", 0x00000001},
101 {"UTF-16", 0x00000002},
102 {"ISO-8859-1", 0x00000004}
106 ValueObj pMsgValueList[] = {
107 {"BINARY", 0x00000001},
108 {"BOOLEAN", 0x00000002},
109 {"DATE", 0x00000004},
110 {"DATE-TIME", 0x00000008},
111 {"FLOAT", 0x00000010},
112 {"INTEGER", 0x00000020},
113 {"PHONE-NUMBER", 0x00000040},
114 {"TEXT", 0x00000080},
115 {"TIME", 0x00000100},
118 {"UTC-OFFSET", 0x00000800},
123 ValueObj pMsgTypeList[] = {
124 {"AIFF", 0x00000001},
127 {"CELL", 0x00000008},
129 {"WORK", 0x00000020},
132 {"HOME", 0x00000100},
133 {"INTL", 0x00000200},
134 {"INTERNET", 0x00000400},
135 {"ISDN", 0x00000800},
136 {"JPEG", 0x00001000},
137 {"MOBILE", 0x00002000},
138 {"MODEM", 0x00004000},
140 {"PAGER", 0x00010000},
141 {"PARCEL", 0x00020000},
145 {"POSTAL", 0x00200000},
146 {"PREF", 0x00400000},
147 {"VIDEO", 0x00800000},
148 {"VOICE", 0x01000000},
149 {"WAVE", 0x02000000},
150 {"WBMP", 0x04000000},
155 /** FUNCTION DECLARATION */
156 int __VMsgGetName(char*, char**, int);
157 int __VMsgGetValue(char*, const ValueObj*, int);
158 int __VMsgGetTypeName(char*, int*, int*);
159 int __VMsgGetParamName(char*, int*, int*);
160 int __VIsVmsgFile(char*, int);
161 char* __VMsgGetParamVal(char*, int*, int*);
162 char* __VMsgGetTypeVal(char*, int*, int*, int, VObject*);
163 char* __VMsgTypeEncode(VObject*, char*);
164 char* __VMsgParamEncode(VObject*, int*);
168 * __VMsgGetName() compares the string and vMsg type, parameter name.
170 * @param szString Name which will compare
171 * @param pszList[] Name list of vMsg type and param
172 * @param size Number of total element of list
174 * @return index The index in the list
177 __VMsgGetName(char* szString, char* pszList[], int size)
180 int high, low, i, diff = 0;
185 for (; high >= low; diff < 0 ? (low = i+1) : (high = i-1)) {
186 i = (low + high) / 2;
187 if ((diff = strcmp(pszList[i], szString)) == 0) /* success: found it */
195 * __VMsgGetValue() compares the string and vMsg type, parameter value.
197 * @param szString Value which will compare
198 * @param list[] Value list of vMsg param
199 * @param size Number of total element of list
201 * @return flag The value's flag.
204 __VMsgGetValue(char* szString, const ValueObj list[], int size)
207 int i = 0, diff = -1;
208 char* szTemp = szString;
210 SysRequireEx(szString, UNKNOWN_NAME);
211 SysRequireEx(size > 0, UNKNOWN_NAME);
213 UPPER(szTemp, i, strlen(szTemp));
215 for (i = 0; i < size-1; i++) {
216 VDATA_TRACE(" i : %d", i);
217 VDATA_TRACE(" for loop %d < %d, list[%d] : %p, list[%d].szName : %p", i, size, i, list[i], i, list[i].szName);
218 VDATA_TRACE(" i : %d", i);
219 if (list[i].szName != NULL) {
220 VDATA_TRACE(" list[%d].szName != NULL", i);
221 VDATA_TRACE(" before strcmp %s %s", list[i].szName, szTemp);
222 VDATA_TRACE(" before strcmp %d", strcmp(list[i].szName, szTemp));
223 if ((diff = strcmp(list[i].szName, szTemp)) == 0) { /* success: found it */
224 VDATA_TRACE(" return %d", list[i].flag);
228 VDATA_TRACE(" after strcmp %s %s", list[i].szName, szTemp);
231 VDATA_TRACE(" return UNKNOWN_NAME");
237 * __VMsgGetTypeName() fine the type name and returns the index number
239 * @param pVMsgRaw The raw data
240 * @param pStatus Decoder status
241 * @param pDLen retrived length
243 * @return res The index in type list
246 __VMsgGetTypeName(char* pVMsgRaw, int* pStatus, int* pDLen)
251 char name[MAX_TYPE_NAME_LEN+1] = {0,};
253 SysRequireEx(pVMsgRaw, UNKNOWN_NAME);
260 GO_NEXT_CHAR(c, pVMsgRaw, pDLen);
263 * TYPE NAME's length is must be less than MAX_TYPE_NAME_LEN.
264 * If TYPE NAME's value is over MAX_TYPE_NAME_LEN, return UNKNOWN_NAME.
265 * And then Decoding Step shoud not be changed.
267 if (index >= MAX_TYPE_NAME_LEN) {
268 *pStatus = VMSG_TYPE_NAME_STATUS;
274 * There is a delimeter between TYPE NAME and next element(=Param, or Type Value).
275 * If VTYPE_TOKEN_SEMICOLON or VTYPE_TOKEN_COLON is faced with,
276 * find TYPE NAME's value in pszMsgTypeList, and then return searched result.
278 if ((c == VTYPE_TOKEN_SEMICOLON) || (c == VTYPE_TOKEN_COLON)) {
281 UPPER(name, i, index);
282 res = __VMsgGetName(name, (char**)pszMsgTypeList, VMSG_TYPE_NUM);
286 * There is no new line in TYPE NAME.
287 * If new line character is faced with, return UNKNOWN_NAME;
289 else if ((c == '\r') || (c == '\n')) {
291 *pStatus = VMSG_TYPE_NAME_STATUS;
294 } else if (_VIsSpace(c)) {
303 if (c == VTYPE_TOKEN_SEMICOLON)
305 * This case next token is parameter. So set VMSG_PARAM_NAME_STATUS step.
307 *pStatus = VMSG_PARAM_NAME_STATUS;
309 if (res != UNKNOWN_NAME)
311 * This case next string is value. So set VMSG_TYPE_VALUE_STATUS step.
313 *pStatus = VMSG_TYPE_VALUE_STATUS;
316 * In current step, TYPE NAME is invalid. So Try to get TYPE NAME again from next position.
318 *pStatus = VMSG_TYPE_NAME_STATUS;
325 * __VMsgGetParamName() fine the param name and returns the index number
327 * @param pVMsgRaw The raw data
328 * @param pStatus Decoder status
329 * @param pDLen retrived length
331 * @return res The index in type list
334 __VMsgGetParamName(char* pVMsgRaw, int* pStatus, int* pDLen)
340 char name[MAX_PARAM_NAME_LEN+1] = {0,};
341 char* pTemp = pVMsgRaw;
343 SysRequireEx(pVMsgRaw, UNKNOWN_NAME);
349 GO_NEXT_CHAR(c, pVMsgRaw, pDLen);
352 * PARAM NAME's length is must be less than MAX_PARAM_NAME_LEN.
353 * If PARAM NAME's value is over MAX_PARAM_NAME_LEN, return UNKNOWN_NAME.
354 * And then Decoding Step shoud not be changed.
356 if (index >= MAX_PARAM_NAME_LEN) {
357 *pStatus = VMSG_TYPE_NAME_STATUS;
363 * There is a delimeter between PARAM NAME and next element(=Param, or Param Value).
364 * If VTYPE_TOKEN_EQUAL is faced with,
365 * find PARAM NAME's value in pszMsgParamList, and then return searched result.
367 if (c == VTYPE_TOKEN_EQUAL) {
370 UPPER(name, i, index);
371 res = __VMsgGetName(name, (char**)pszMsgParamList, VMSG_PARAM_NUM);
372 if (res == UNKNOWN_NAME)
374 *pStatus = VMSG_PARAM_VALUE_STATUS;
378 * This case, There is no parameter type. Only Parameter Value.
379 * In VMSG_PARAM_NAME_STATUS status, VTYPE_TOKEN_COLON means that anything parameter is no more.
380 * so set next step to VMSG_PARAM_VALUE_STATUS.
382 * Ex) TEL;WORK:+12341234
383 * ------ ":" next is TEL TYPE's value.
385 * VMSG_PARAM_NAME_STATUS(current) -> VMSG_PARAM_VALUE_STATUS
386 * -> VMSG_TYPE_VALUE_STATUS -> MOVE TO NEXT TYPE
388 else if (c == VTYPE_TOKEN_COLON) {
389 *pStatus = VMSG_PARAM_VALUE_STATUS;
396 * This case, There is no parameter type. Only Parameter Value.
397 * In VMSG_PARAM_NAME_STATUS status, VTYPE_TOKEN_SEMICOLON means that there is a next parameter.
398 * so set next step to VMSG_PARAM_NAME_STATUS.
400 * Ex) TEL;WORK;PREF:+12341234
401 * ------ ":" next is TEL TYPE's value.
403 * VMSG_PARAM_NAME_STATUS(current) -> VMSG_PARAM_NAME_STATUS
404 * -> VMSG_PARAM_VALUE_STATUS -> VMSG_TYPE_VALUE_STATUS -> MOVE TO NEXT TYPE
406 else if (c == VTYPE_TOKEN_SEMICOLON) {
407 *pStatus = VMSG_PARAM_NAME_STATUS;
412 } else if ((c == '\r') || (c == '\n') || (_VIsSpace(c))) {
422 __VMsgFreeVTreeMemory(VTree * pTree)
425 VObject* pCurObj = NULL;
426 VObject* pNextObj = NULL;
428 VTree* pCurTree = NULL;
429 VTree* pNextTree = NULL;
431 VParam* pCurParam = NULL;
432 VParam* pNextParam = NULL;
437 SysRequireEx(pTree->treeType == VMESSAGE, false);
438 SysRequireEx(pTree != NULL, false);
439 VDATA_TRACE("vmsg_free_vtree_memory() entered.");
441 if (pTree->treeType != VMESSAGE) {
449 pNextTree = pCurTree->pNext;
450 pCurObj = pCurTree->pTop;
454 pNextObj = pCurObj->pSibling;
455 count = pCurObj->valueCount;
457 for (i = 0; i < count; i++)
458 VFREE(pCurObj->pszValue[i]);
460 if (pCurObj->pParam) {
462 pCurParam = pCurObj->pParam;
464 while (pCurParam != NULL) {
465 pNextParam = pCurParam->pNext;
466 VDATA_TRACE("pNEXT ==> %p", pCurParam->pNext);
467 VDATA_TRACE("pPARAM ==> %p", pCurParam->parameter);
468 VDATA_TRACE("pVALUE ==> %p", pCurParam->paramValue);
469 VDATA_TRACE("pCurParam : %p", pCurParam);
470 VDATA_TRACE("pCurParam->parameter : %d", pCurParam->parameter);
471 VDATA_TRACE("pCurParam->paramValue : %d", pCurParam->paramValue);
472 if (pNextParam != NULL) {
473 VDATA_TRACE("pNextParam : %p", pNextParam);
474 VDATA_TRACE("pNextParam->parameter : %d", pNextParam->parameter);
475 VDATA_TRACE("pNextParam->paramValue : %d", pNextParam->paramValue);
478 pCurParam = pNextParam;
487 pCurTree = pNextTree;
490 VDATA_TRACE("exit vmsg_free_vtree_memory");
496 * __VMsgGetParamVal() fine the param value and returns value.
498 * @param pVMsgRaw The raw data
499 * @param pStatus Decoder status
500 * @param pDLen retrived length
502 * @return buffer The result value
505 __VMsgGetParamVal(char* pVMsgRaw, int* pStatus, int* pDLen)
511 char* pTemp = pVMsgRaw;
513 SysRequireEx(pVMsgRaw, NULL);
516 GO_NEXT_CHAR(c, pVMsgRaw, pDLen);
519 case VTYPE_TOKEN_SEMICOLON:
520 *pStatus = VMSG_PARAM_NAME_STATUS;
522 case VTYPE_TOKEN_COLON:
523 *pStatus = VMSG_TYPE_VALUE_STATUS;
525 case VTYPE_TOKEN_COMMA:
526 *pStatus = VMSG_PARAM_VALUE_STATUS;
529 if (c == VTYPE_TOKEN_SEMICOLON
530 || c == VTYPE_TOKEN_COLON
531 || c == VTYPE_TOKEN_COMMA
536 if (len < 1 || (pBuf = (char *)calloc(1, len)) == NULL)
538 memset(pBuf, 0x00, len);
539 memcpy(pBuf, pTemp, len-1);
547 * __VMsgGetTypeVal() fine the type value and returns value.
549 * @param pVMsgRaw The raw data
550 * @param status Decoder status
551 * @return buffer The result value
554 __VMsgGetTypeVal(char* pVMsgRaw, int* pStatus, int* pDLen, int enc, VObject* pType)
561 bool bEscape = false;
565 char* pTemp = pVMsgRaw;
566 char* pTmpBuf = NULL;
570 SysRequireEx(pVMsgRaw, NULL);
571 VDATA_TRACE("pVMsgRaw: %s", pVMsgRaw);
573 GO_NEXT_CHAR(c, pVMsgRaw, pDLen);
580 /** This case means that there are more type's value. */
581 if (c == VTYPE_TOKEN_SEMICOLON && bEscape == false) {
582 if ((pBuf = (char *)calloc(1, len)) == NULL)
585 memset(pBuf, 0x00, len);
586 memcpy(pBuf, pTemp, len-1);
591 *pStatus = VMSG_TYPE_VALUE_STATUS;
593 /** Base 64 Decoding */
594 if ((enc & pMsgEncList[1].flag) || (enc & pMsgEncList[0].flag)) {
596 bufferCount = (len * 6 / 8) + 2;
598 if ((pTmpBuf = (char *)calloc(1, bufferCount)) == NULL) {
603 memset(pTmpBuf, 0x00, bufferCount);
604 num = _VB64Decode(pTmpBuf, pBuf);
607 pType->numOfBiData = num;
615 /** Quoted Printable Decoding */
616 if (enc & pMsgEncList[2].flag) {
621 if (pBuf[i] == '\n' || pBuf[i] == '\r') {
623 if (pBuf[i] == '\n' || pBuf[i] == '\r')
626 if (pBuf[j-1] == '=')
629 pBuf[j++] = pBuf[i++];
642 else if (bEscape == true && c != VTYPE_TOKEN_SEMICOLON)
644 else if ((c == '\r') || (c == '\n')) {
647 if (c2 == '=' && (enc & pMsgEncList[2].flag)) {
649 if ((c1 == '\r') || (c1 == '\n')) {
654 } else if (__VMsgGetTypeName(pVMsgRaw, &Status, &Len) != UNKNOWN_NAME) {
655 if ((pBuf = (char *)calloc(1, len)) == NULL)
658 memset(pBuf, 0x00, len);
659 memcpy(pBuf, pTemp, len-1);
663 VDATA_TRACE("pVMsgRaw: %s", pVMsgRaw);
664 *pStatus = VMSG_TYPE_NAME_STATUS;
668 if ((c1 == '\r') || (c1 == '\n')) {
673 if ((enc & pMsgEncList[1].flag) || (enc & pMsgEncList[0].flag)) {
675 bufferCount = (len * 6 / 8) + 5;
677 if ((pTmpBuf = (char *)calloc(1, bufferCount)) == NULL) {
682 memset(pTmpBuf, 0x00, bufferCount);
683 num = _VB64Decode(pTmpBuf, pBuf);
686 pType->numOfBiData = num;
694 if (enc & pMsgEncList[2].flag) {
699 if (pBuf[i] == '\n' || pBuf[i] == '\r') {
701 if (pBuf[i] == '\n' || pBuf[i] == '\r')
704 if (pBuf[j-1] == '=') j--;
706 pBuf[j++] = pBuf[i++];
725 VMsgGetTypeValue(int index)
728 VDATA_TRACE("VMsgGetTypeValue() enter..\n");
730 return pMsgTypeList[index].flag;
734 VMsgGetValValue(int index)
737 VDATA_TRACE("VMsgGetValValue() enter..\n");
739 return pMsgValueList[index].flag;
743 VMsgGetEncValue(int index)
746 VDATA_TRACE("VMsgGetEncValue() enter..\n");
748 return pMsgEncList[index].flag;
752 VMsgGetCharsetValue(int index)
755 VDATA_TRACE("VMsgGetCharsetValue() enter..\n");
757 return pMsgCharsetList[index].flag;
761 * vmsg_decode() decode the vMsg data and returns vObject struct
763 * @param pVMsgRaw The raw data
764 * @return vObject The result value
766 VTree* vmsg_decode(char *pMsgRaw)
770 char* szValue = NULL;
771 char* szMsgBegin = NULL;
772 char* pMsgRawTmp = NULL;
774 VTree* pVBody = NULL;
775 VTree* pCurrent = NULL;
776 VTree* pVCard = NULL;
777 VParam* pTmpParam = NULL;
778 VObject* pTemp = NULL;
783 int status = VMSG_TYPE_NAME_STATUS;
788 int param_status = false;
789 int numberedParam = 0;
793 bool vmsg_ended = false;
795 SysRequireEx(pMsgRaw != NULL, NULL);
796 len = strlen(pMsgRaw);
797 VDATA_TRACE("length of pCardRaw = %d", len);
799 len = _VUnfoldingNoSpec(pMsgRaw, VMESSAGE);
800 pMsgRawTmp = pMsgRaw;
801 len = _VManySpace2Space(pMsgRaw);
803 VDATA_TRACE("ret value of _VManySpace2Space = %d", len);
805 if (!__VIsVmsgFile(pMsgRaw, CHECK_START)) {
811 while (true && !done) {
814 if ((c == '\0') || done)
818 case VMSG_TYPE_NAME_STATUS:
820 type = __VMsgGetTypeName(pMsgRaw, &status, &dLen);
822 if (type == VMSG_TYPE_BEGIN)
831 case VMSG_TYPE_BEGIN:
834 szMsgBegin = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, NULL);
837 if (szMsgBegin == NULL)
840 if (!strncmp(szMsgBegin, "VCARD", strlen("VCARD"))) {
841 VDATA_TRACE("pVTree: %s", pVTree);
842 pVCard = vcard_decode(pVTree);
844 pCurrent->pNext = pVCard;
848 dLen = ((strstr(pMsgRaw, "END:VCARD") + 9) - pMsgRaw);
851 if (!strncmp(szMsgBegin, "VMSG", strlen("VMSG"))) {
852 if ((pVMsg = (VTree*)calloc(1, sizeof(VTree))) == NULL) {
855 memset(pVMsg, 0x00, sizeof(VTree));
857 pVMsg->treeType = VMESSAGE;
862 } else if (!strncmp(szMsgBegin, "VBODY", strlen("VBODY"))) {
863 if ((pVBody = (VTree*)calloc(1, sizeof(VTree))) == NULL) {
867 memset(pVBody, 0x00, sizeof(VTree));
868 pVBody->treeType = VBODY;
871 pVBody->pNext = NULL;
873 pCurrent->pNext = pVBody;
884 /* szMsgBegin = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, NULL); */
886 if (!strncmp(pMsgRaw, "VMSG", strlen("VMSG"))) {
890 status = VMSG_TYPE_NAME_STATUS;
891 /* pMsgRaw += dLen; */
893 VDATA_TRACE("pMsgRaw:%s", pMsgRaw);
901 if (UNKNOWN_NAME == type || type < 0) {
902 status = VMSG_TYPE_NAME_STATUS;
906 if ((pTemp = (VObject*)calloc(1, sizeof(VObject))) == NULL)
909 memset(pTemp, 0, sizeof(VObject));
910 pTemp->property = type;
913 if (pCurrent->pTop == NULL) {
914 pCurrent->pTop = pTemp;
915 pCurrent->pCur = pTemp;
917 pCurrent->pCur->pSibling = pTemp;
918 pCurrent->pCur = pTemp;
926 param_status = false;
930 case VMSG_PARAM_NAME_STATUS:
933 param = __VMsgGetParamName(pMsgRaw, &status, &dLen);
936 if (param_status != true) {
938 if ((pTmpParam = (VParam*)calloc(1, sizeof(VParam))) == NULL)
943 pCurrent->pCur->pParam = pTmpParam;
944 memset(pTmpParam, 0x00, sizeof(VParam));
945 VDATA_TRACE("pTmpParam : %p", pTmpParam);
947 if ((pTmpParam->pNext = (VParam*)calloc(1, sizeof(VParam))) == NULL)
950 pTmpParam = pTmpParam->pNext;
951 memset(pTmpParam, 0x00, sizeof(VParam));
952 VDATA_TRACE("pTmpParam : %p", pTmpParam);
955 pTmpParam->parameter = param;
958 case VMSG_PARAM_VALUE_STATUS:
961 switch (pTmpParam->parameter) {
962 case VMSG_PARAM_TYPE:
963 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
964 numberedParam |= __VMsgGetValue(szValue, pMsgTypeList, VMSG_TYPE_PARAM_NUM);
966 case VMSG_PARAM_VALUE:
967 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
968 numberedParam |= __VMsgGetValue(szValue, pMsgValueList, VMSG_VALUE_PARAM_NUM);
970 case VMSG_PARAM_ENCODING:
971 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
972 numberedParam |= __VMsgGetValue(szValue, pMsgEncList, VMSG_ENCODE_PARAM_NUM);
975 case VMSG_PARAM_CHARSET:
976 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
977 numberedParam |= __VMsgGetValue(szValue, pMsgCharsetList, VMSG_CHARSET_PARAM_NUM);
979 case VMSG_PARAM_CONTEXT:
980 case VMSG_PARAM_LANGUAGE:
981 /* prevent 7605 08.03.13 */
982 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
986 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
988 SET_PARAM_VALUE(numberedParam, szValue, pMsgTypeList, VMSG_TYPE_PARAM_NUM, pTmpParam, VMSG_PARAM_TYPE, enc);
989 SET_PARAM_VALUE(numberedParam, szValue, pMsgValueList, VMSG_VALUE_PARAM_NUM, pTmpParam, VMSG_PARAM_VALUE, enc);
990 SET_PARAM_VALUE(numberedParam, szValue, pMsgEncList, VMSG_ENCODE_PARAM_NUM, pTmpParam, VMSG_PARAM_ENCODING, enc);
991 SET_PARAM_VALUE(numberedParam, szValue, pMsgCharsetList, VMSG_CHARSET_PARAM_NUM, pTmpParam, VMSG_PARAM_CHARSET, enc);
1000 VDATA_TRACE("%d, %s, %p", numberedParam, szValue, pTmpParam);
1001 pTmpParam->paramValue = numberedParam;
1002 pTmpParam->pNext = NULL;
1006 case VMSG_TYPE_VALUE_STATUS:
1008 temp = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, pCurrent->pCur);
1010 if (valueCount < VDATA_VALUE_COUNT_MAX) {
1011 pCurrent->pCur->pszValue[valueCount] = temp;
1013 pCurrent->pCur->valueCount = valueCount;
1014 VDATA_TRACE("object property: %d, value: %s", pCurrent->pCur->property, pCurrent->pCur->pszValue[valueCount - 1]);
1022 VDATA_TRACE("pMsgRawTmp: %s", pMsgRawTmp);
1023 /* VFREE(pMsgRawTmp); */
1025 if (pVMsg && pVMsg->pTop == NULL) {
1026 VDATA_TRACE("pVMsg->Top: NULL");
1031 VDATA_TRACE("vmsg_ended: false");
1045 vmsg_free_vtree_memory(pVMsg);
1051 * vmsg_encode() compares the string and vMsg type, parameter value.
1053 * @param pVMsgRaw Data which will be encoded
1054 * @return char * Encoded result
1056 char* vmsg_encode(VTree *pVMsgRaw)
1059 char* pVMsgRes = NULL;
1060 char* pTmpVMsgRes = NULL;
1061 VTree* pTmpTree = NULL;
1062 VObject * pTmpObj = NULL;
1068 if (!pVMsgRaw || !pVMsgRaw->pTop) {
1072 for (; cnt < pVMsgRaw->pTop->valueCount; cnt++) {
1074 if (pVMsgRaw->pTop->pszValue[cnt] == NULL) {
1075 VDATA_TRACE("pVMsgRaw->pTop->valueCount : %d", pVMsgRaw->pTop->valueCount);
1076 VDATA_TRACE("pVMsgRaw->pTop->pszValue[%d] : %s", cnt, pVMsgRaw->pTop->pszValue[cnt]);
1082 pTmpTree = pVMsgRaw;
1083 pTmpObj = pVMsgRaw->pTop;
1086 switch (pTmpTree->treeType) {
1093 if ((pVMsgRes = (char *)calloc(1, sizeof(char) * (total += 13))) == NULL) {
1094 VDATA_TRACE("vmsg_encode:calloc failed\n");
1098 memcpy(pVMsgRes, "BEGIN:VMSG\r\n", 13);
1102 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, sizeof(char) * (total += 14))) == NULL) {
1103 VDATA_TRACE("vmsg_encode:realloc failed\n");
1109 pVMsgRes = pTmpVMsgRes;
1110 g_strlcat(pVMsgRes, "BEGIN:VBODY\r\n", 13);
1118 if (pTmpObj == NULL)
1121 if ((pTemp = __VMsgTypeEncode(pTmpObj, pTmpObj->property == VCARD_TYPE_TEL ? "TEL" : pszMsgTypeList[pTmpObj->property])) != NULL) {
1122 if (pTmpTree->treeType == VCARD) {
1123 char* encoded = NULL;
1125 encoded = vcard_encode(pTmpTree);
1126 if (encoded == NULL) {
1127 VDATA_TRACE("vcard_encode() failed\n");
1134 len = strlen(encoded);
1136 if ((pTmpVMsgRes = (char*)realloc(pVMsgRes, (total += len+10))) == NULL) {
1137 VDATA_TRACE("vmsg_encode():realloc failed\n");
1145 pVMsgRes = pTmpVMsgRes;
1146 g_strlcat(pVMsgRes, encoded, len+10);
1147 VDATA_TRACE("pTemp : %s", encoded);
1152 len = strlen(pTemp);
1154 if ((pTmpVMsgRes = (char*)realloc(pVMsgRes, (total += len+10))) == NULL) {
1155 VDATA_TRACE("vmsg_encode():realloc failed\n");
1161 pVMsgRes = pTmpVMsgRes;
1162 g_strlcat(pVMsgRes, pTemp, len+10);
1163 VDATA_TRACE("pTemp : %s", pTemp);
1166 if (pTmpObj->pSibling != NULL)
1167 pTmpObj = pTmpObj->pSibling;
1174 switch (pTmpTree->treeType) {
1176 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, (total += 12))) == NULL) {
1178 VDATA_TRACE("vcal_encode():realloc failed\n");
1182 pVMsgRes = pTmpVMsgRes;
1183 g_strlcat(pVMsgRes, "END:VBODY\r\n", 12);
1194 if (pTmpTree->pNext != NULL)
1195 pTmpTree = pTmpTree->pNext;
1198 pTmpObj = pTmpTree->pTop;
1201 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, (total += 11))) == NULL) {
1202 VDATA_TRACE("vmsg_encode:realloc failed\n");
1208 pVMsgRes = pTmpVMsgRes;
1209 g_strlcat(pVMsgRes, "END:VMSG\r\n", 11);
1216 * VIsVmsgFile() verify VMsg file.
1218 * @param pVMsgRaw Data which will be encoded
1219 * @return int result (true or false)
1222 __VIsVmsgFile(char *pMsgRaw, int mode)
1225 bool rtnValue = true;
1226 char *pszVmsgBegin = "BEGIN:VMSG";
1230 for (i = 0; i < 10; i++)
1231 if (*pszVmsgBegin++ != *pMsgRaw++)
1244 * vMsgTypeEncoder() compares the string and vMsg type, parameter value.
1246 * @param typeObj Data which will be encoded
1247 * @param type Name of the type
1248 * @return char * Encoded result
1251 __VMsgTypeEncode(VObject *pTypeObj, char *pType)
1256 char* szTypeValue = NULL;
1257 char* szTemp = NULL;
1260 char* pEncode = NULL;
1265 len = strlen(pType);
1266 biLen = pTypeObj->numOfBiData;
1268 if ((szTypeValue = (char *)calloc(1, total += (len+1))) == NULL) {
1269 VDATA_TRACE("__VMsgTypeEncode():calloc failed\n");
1273 memset(szTypeValue, '\0', (len+1));
1274 g_strlcat(szTypeValue, pType, len+1);
1276 pTemp = __VMsgParamEncode(pTypeObj, &enc);
1277 if (pTemp != NULL) {
1278 len = strlen(pTemp);
1279 if ((szTemp = (char *)realloc(szTypeValue, (total += len))) == NULL) {
1280 VDATA_TRACE("__VMsgTypeEncode():realloc failed\n");
1287 szTypeValue = szTemp;
1289 g_strlcat(szTypeValue, pTemp, len);
1294 if ((szTemp = (char *)realloc(szTypeValue, (total += 2))) == NULL) {
1299 szTypeValue = szTemp;
1302 g_strlcat(szTypeValue, ":", 2);
1306 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1307 for (i = 0; i < pTypeObj->valueCount; i++) {
1309 if (pTypeObj->pszValue[i] != NULL)
1310 len += strlen(pTypeObj->pszValue[i]);
1316 for (i = 0; i < pTypeObj->valueCount; i++) {
1319 if ((pEncode = (char *)calloc(1, len+20)) == NULL) {
1325 memset(pEncode, '\0', len+20);
1327 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1328 g_strlcat(pEncode, pTypeObj->pszValue[i], 20);
1331 memcpy(pEncode, pTypeObj->pszValue[i], biLen);
1334 strncpy(buf, pTypeObj->pszValue[i], 999);
1336 g_strlcat(pEncode, ";" , len+20);
1337 g_strlcat(pEncode, buf , len+20);
1341 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1343 g_strlcat(pEncode, "\0\0", 2);
1344 len = strlen(pEncode);
1350 if (enc & pMsgEncList[2].flag) {
1351 if ((pRes = (char *)calloc(1, len * 6 + 10)) == NULL) {
1358 _VQPEncode(pRes, pEncode);
1360 } else if (enc & pMsgEncList[1].flag) {
1361 if ((pRes = (char *)calloc(1, (len * 8 / 6) + 48)) == NULL) {
1368 memset(pRes, '\0', ((len * 8 / 6) + 48));
1369 _VB64Encode(pRes, pEncode, biLen);
1370 VDATA_TRACE("Origin Size: %d, Allocated Size %d, Coverted Size: %d\n", biLen, (len * 8 / 6) + 48, strlen(pRes));
1373 if ((pRes = (char *)calloc(1, len+30)) == NULL) {
1379 memset(pRes, '\0', (len + 30));
1381 memcpy(pRes, pEncode, len);
1386 if ((szTemp = (char *)realloc(pRes, strlen(pRes) + 3)) == NULL) {
1395 g_strlcat(pRes, "\r\n", strlen(pRes) + 2);
1399 if ((szTemp = (char *)realloc(szTypeValue, (total += (len+3)))) == NULL) {
1406 szTypeValue = szTemp;
1409 g_strlcat(szTypeValue, pRes, total - 1);
1411 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1412 _VRLSpace(szTypeValue);
1413 _VRTSpace(szTypeValue);
1423 * __VMsgParamEncode() Parameter Encoding.
1425 * @param pTypeObj Data which will be encoded
1426 * @param pEnc Name of the type
1429 __VMsgParamEncode(VObject* pTypeObj, int* pEnc)
1437 char* szParam = NULL;
1438 char* szTemp = NULL;
1439 VParam* pTemp = NULL;
1440 ValueObj* pList = NULL;
1442 /** Paramter initialize. */
1443 pTemp = pTypeObj->pParam;
1445 /** Momory Allocation for parameter string. */
1446 if (pTemp != NULL) {
1447 if ((szParam = (char*)calloc(1, len += 2)) == NULL) {
1451 memset(szParam, 0x00, 2);
1454 /** appending pamaters. */
1457 if (pTemp == NULL) break;
1461 /** Expand szParam string. For appending.*/
1462 if ((szTemp = (char *)realloc(szParam, len += 15)) == NULL) {
1470 /** appending paramter name. */
1471 g_strlcat(szParam, ";" , len);
1472 if (pTemp->parameter != VMSG_PARAM_TYPE) {
1473 g_strlcat(szParam, pszMsgParamList[pTemp->parameter], len);
1474 g_strlcat(szParam, "=", len);
1477 /** Set Parameter Value name. */
1478 switch (pTemp->parameter) {
1479 case VMSG_PARAM_ENCODING:
1480 *pEnc = pMsgEncList[pTemp->paramValue].flag;
1481 shift = VMSG_ENCODE_PARAM_NUM;
1482 pList = pMsgEncList; bSupported = true;
1484 case VMSG_PARAM_TYPE:
1485 shift = VMSG_TYPE_PARAM_NUM;
1486 pList = pMsgTypeList; bSupported = true;
1488 case VMSG_PARAM_VALUE:
1489 shift = VMSG_VALUE_PARAM_NUM;
1490 pList = pMsgValueList; bSupported = true;
1492 case VMSG_PARAM_CHARSET:
1493 shift = VMSG_CHARSET_PARAM_NUM;
1494 pList = pMsgCharsetList; bSupported = true;
1497 if ((szTemp = (char*)realloc(szParam, 5)) == NULL) {
1504 g_strlcat(szParam, "NONE", strlen("NONE"));
1507 /** exchage parameter value's to string.*/
1508 if (bSupported == true) {
1510 for (i = 0, sNum = 0x00000001; i < shift; i++) {
1512 if (pList[pTemp->paramValue].flag & sNum) {
1513 if ((szTemp = (char *)realloc(szParam, (len += (strlen(pList[i].szName) + 2)))) == NULL) {
1521 g_strlcat(szParam, pList[i].szName, len);
1522 g_strlcat(szParam, "; ", len);
1529 /** remove semicolon from tail. */
1530 for (i = strlen(szParam); i > 0 ; i--) {
1532 if (szParam[i] == ' ' && szParam[i-1] == ';') {
1533 szParam[i-1] = '\0';
1538 if (pTemp->pNext != NULL)
1539 pTemp = pTemp->pNext;
1548 vmsg_free_vtree_memory(VTree * pTree)
1551 if (pTree == NULL) {
1556 return __VMsgFreeVTreeMemory(pTree);