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) {
375 *pStatus = VMSG_PARAM_VALUE_STATUS;
379 * This case, There is no parameter type. Only Parameter Value.
380 * In VMSG_PARAM_NAME_STATUS status, VTYPE_TOKEN_COLON means that anything parameter is no more.
381 * so set next step to VMSG_PARAM_VALUE_STATUS.
383 * Ex) TEL;WORK:+12341234
384 * ------ ":" next is TEL TYPE's value.
386 * VMSG_PARAM_NAME_STATUS(current) -> VMSG_PARAM_VALUE_STATUS
387 * -> VMSG_TYPE_VALUE_STATUS -> MOVE TO NEXT TYPE
389 else if (c == VTYPE_TOKEN_COLON) {
390 *pStatus = VMSG_PARAM_VALUE_STATUS;
397 * This case, There is no parameter type. Only Parameter Value.
398 * In VMSG_PARAM_NAME_STATUS status, VTYPE_TOKEN_SEMICOLON means that there is a next parameter.
399 * so set next step to VMSG_PARAM_NAME_STATUS.
401 * Ex) TEL;WORK;PREF:+12341234
402 * ------ ":" next is TEL TYPE's value.
404 * VMSG_PARAM_NAME_STATUS(current) -> VMSG_PARAM_NAME_STATUS
405 * -> VMSG_PARAM_VALUE_STATUS -> VMSG_TYPE_VALUE_STATUS -> MOVE TO NEXT TYPE
407 else if (c == VTYPE_TOKEN_SEMICOLON) {
408 *pStatus = VMSG_PARAM_NAME_STATUS;
413 } else if ((c == '\r') || (c == '\n') || (_VIsSpace(c))) {
423 __VMsgFreeVTreeMemory(VTree * pTree)
426 VObject* pCurObj = NULL;
427 VObject* pNextObj = NULL;
429 VTree* pCurTree = NULL;
430 VTree* pNextTree = NULL;
432 VParam* pCurParam = NULL;
433 VParam* pNextParam = NULL;
438 SysRequireEx(pTree->treeType == VMESSAGE, false);
439 SysRequireEx(pTree != NULL, false);
440 VDATA_TRACE("vmsg_free_vtree_memory() entered.");
442 if (pTree->treeType != VMESSAGE) {
450 pNextTree = pCurTree->pNext;
451 pCurObj = pCurTree->pTop;
455 pNextObj = pCurObj->pSibling;
456 count = pCurObj->valueCount;
458 for (i = 0; i < count; i++) {
459 VFREE(pCurObj->pszValue[i]);
462 if (pCurObj->pParam) {
464 pCurParam = pCurObj->pParam;
466 while (pCurParam != NULL) {
467 pNextParam = pCurParam->pNext;
468 VDATA_TRACE("pNEXT ==> %p", pCurParam->pNext);
469 VDATA_TRACE("pPARAM ==> %p", pCurParam->parameter);
470 VDATA_TRACE("pVALUE ==> %p", pCurParam->paramValue);
471 VDATA_TRACE("pCurParam : %p", pCurParam);
472 VDATA_TRACE("pCurParam->parameter : %d", pCurParam->parameter);
473 VDATA_TRACE("pCurParam->paramValue : %d", pCurParam->paramValue);
474 if (pNextParam != NULL) {
475 VDATA_TRACE("pNextParam : %p", pNextParam);
476 VDATA_TRACE("pNextParam->parameter : %d", pNextParam->parameter);
477 VDATA_TRACE("pNextParam->paramValue : %d", pNextParam->paramValue);
480 pCurParam = pNextParam;
489 pCurTree = pNextTree;
492 VDATA_TRACE("exit vmsg_free_vtree_memory");
498 * __VMsgGetParamVal() fine the param value and returns value.
500 * @param pVMsgRaw The raw data
501 * @param pStatus Decoder status
502 * @param pDLen retrived length
504 * @return buffer The result value
507 __VMsgGetParamVal(char* pVMsgRaw, int* pStatus, int* pDLen)
513 char* pTemp = pVMsgRaw;
515 SysRequireEx(pVMsgRaw, NULL);
518 GO_NEXT_CHAR(c, pVMsgRaw, pDLen);
521 case VTYPE_TOKEN_SEMICOLON:
522 *pStatus = VMSG_PARAM_NAME_STATUS;
524 case VTYPE_TOKEN_COLON:
525 *pStatus = VMSG_TYPE_VALUE_STATUS;
527 case VTYPE_TOKEN_COMMA:
528 *pStatus = VMSG_PARAM_VALUE_STATUS;
531 if (c == VTYPE_TOKEN_SEMICOLON
532 || c == VTYPE_TOKEN_COLON
533 || c == VTYPE_TOKEN_COMMA
538 if (len < 1 || (pBuf = (char *)calloc(1, len)) == NULL)
540 memset(pBuf, 0x00, len);
541 memcpy(pBuf, pTemp, len-1);
549 * __VMsgGetTypeVal() fine the type value and returns value.
551 * @param pVMsgRaw The raw data
552 * @param status Decoder status
553 * @return buffer The result value
556 __VMsgGetTypeVal(char* pVMsgRaw, int* pStatus, int* pDLen, int enc, VObject* pType)
563 bool bEscape = false;
567 char* pTemp = pVMsgRaw;
568 char* pTmpBuf = NULL;
572 SysRequireEx(pVMsgRaw, NULL);
573 VDATA_TRACE("pVMsgRaw: %s", pVMsgRaw);
575 GO_NEXT_CHAR(c, pVMsgRaw, pDLen);
582 /** This case means that there are more type's value. */
583 if (c == VTYPE_TOKEN_SEMICOLON && bEscape == false) {
584 if ((pBuf = (char *)calloc(1, len)) == NULL)
587 memset(pBuf, 0x00, len);
588 memcpy(pBuf, pTemp, len-1);
593 *pStatus = VMSG_TYPE_VALUE_STATUS;
595 /** Base 64 Decoding */
596 if ((enc & pMsgEncList[1].flag) || (enc & pMsgEncList[0].flag)) {
598 bufferCount = (len * 6 / 8) + 2;
600 if ((pTmpBuf = (char *)calloc(1, bufferCount)) == NULL) {
605 memset(pTmpBuf, 0x00, bufferCount);
606 num = _VB64Decode(pTmpBuf, pBuf);
609 pType->numOfBiData = num;
617 /** Quoted Printable Decoding */
618 if (enc & pMsgEncList[2].flag) {
623 if (pBuf[i] == '\n' || pBuf[i] == '\r') {
625 if (pBuf[i] == '\n' || pBuf[i] == '\r')
628 if (pBuf[j-1] == '=')
631 pBuf[j++] = pBuf[i++];
644 else if (bEscape == true && c != VTYPE_TOKEN_SEMICOLON)
646 else if ((c == '\r') || (c == '\n')) {
649 if (c2 == '=' && (enc & pMsgEncList[2].flag)) {
651 if ((c1 == '\r') || (c1 == '\n')) {
656 } else if (__VMsgGetTypeName(pVMsgRaw, &Status, &Len) != UNKNOWN_NAME) {
657 if ((pBuf = (char *)calloc(1, len)) == NULL)
660 memset(pBuf, 0x00, len);
661 memcpy(pBuf, pTemp, len-1);
665 VDATA_TRACE("pVMsgRaw: %s", pVMsgRaw);
666 *pStatus = VMSG_TYPE_NAME_STATUS;
670 if ((c1 == '\r') || (c1 == '\n')) {
675 if ((enc & pMsgEncList[1].flag) || (enc & pMsgEncList[0].flag)) {
677 bufferCount = (len * 6 / 8) + 5;
679 if ((pTmpBuf = (char *)calloc(1, bufferCount)) == NULL) {
684 memset(pTmpBuf, 0x00, bufferCount);
685 num = _VB64Decode(pTmpBuf, pBuf);
688 pType->numOfBiData = num;
696 if (enc & pMsgEncList[2].flag) {
701 if (pBuf[i] == '\n' || pBuf[i] == '\r') {
703 if (pBuf[i] == '\n' || pBuf[i] == '\r')
706 if (pBuf[j-1] == '=') j--;
708 pBuf[j++] = pBuf[i++];
727 VMsgGetTypeValue(int index)
730 VDATA_TRACE("VMsgGetTypeValue() enter..\n");
732 return pMsgTypeList[index].flag;
736 VMsgGetValValue(int index)
739 VDATA_TRACE("VMsgGetValValue() enter..\n");
741 return pMsgValueList[index].flag;
745 VMsgGetEncValue(int index)
748 VDATA_TRACE("VMsgGetEncValue() enter..\n");
750 return pMsgEncList[index].flag;
754 VMsgGetCharsetValue(int index)
757 VDATA_TRACE("VMsgGetCharsetValue() enter..\n");
759 return pMsgCharsetList[index].flag;
763 * vmsg_decode() decode the vMsg data and returns vObject struct
765 * @param pVMsgRaw The raw data
766 * @return vObject The result value
768 VTree* vmsg_decode(char *pMsgRaw)
772 char* szValue = NULL;
773 char* szMsgBegin = NULL;
774 char* pMsgRawTmp = NULL;
776 VTree* pVBody = NULL;
777 VTree* pCurrent = NULL;
778 VTree* pVCard = NULL;
779 VParam* pTmpParam = NULL;
780 VObject* pTemp = NULL;
785 int status = VMSG_TYPE_NAME_STATUS;
790 int param_status = false;
791 int numberedParam = 0;
793 int start_status = 0;
796 bool vmsg_ended = false;
798 SysRequireEx(pMsgRaw != NULL, NULL);
799 len = strlen(pMsgRaw);
800 VDATA_TRACE("length of pCardRaw = %d", len);
802 len = _VUnfoldingNoSpec(pMsgRaw, VMESSAGE);
803 pMsgRawTmp = pMsgRaw;
804 len = _VManySpace2Space(pMsgRaw);
806 VDATA_TRACE("ret value of _VManySpace2Space = %d", len);
808 if (!__VIsVmsgFile(pMsgRaw, CHECK_START)) {
814 while (true && !done) {
817 if ((c == '\0') || done)
821 case VMSG_TYPE_NAME_STATUS:
823 type = __VMsgGetTypeName(pMsgRaw, &status, &dLen);
825 if (type == VMSG_TYPE_BEGIN)
834 case VMSG_TYPE_BEGIN:
837 szMsgBegin = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, NULL);
840 if (szMsgBegin == NULL)
843 if (!strncmp(szMsgBegin, "VCARD", strlen("VCARD"))) {
844 VDATA_TRACE("pVTree: %s", pVTree);
845 pVCard = vcard_decode(pVTree);
846 pCurrent->pNext = pVCard;
849 dLen = ((strstr(pMsgRaw, "END:VCARD") + 9) - pMsgRaw);
853 if (start_status == 1)
857 if (!strncmp(szMsgBegin, "VMSG", strlen("VMSG"))) {
858 if ((pVMsg = (VTree*)calloc(1, sizeof(VTree))) == NULL) {
862 memset(pVMsg, 0x00, sizeof(VTree));
864 pVMsg->treeType = VMESSAGE;
869 } else if (!strncmp(szMsgBegin, "VBODY", strlen("VBODY"))) {
870 if ((pVBody = (VTree*)calloc(1, sizeof(VTree))) == NULL) {
875 memset(pVBody, 0x00, sizeof(VTree));
876 pVBody->treeType = VBODY;
879 pVBody->pNext = NULL;
880 pCurrent->pNext = pVBody;
891 //szMsgBegin = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, NULL);
893 if (!strncmp(pMsgRaw, "VMSG", strlen("VMSG"))) {
897 status = VMSG_TYPE_NAME_STATUS;
900 VDATA_TRACE("pMsgRaw:%s", pMsgRaw);
908 if (UNKNOWN_NAME == type || type < 0) {
909 status = VMSG_TYPE_NAME_STATUS;
913 if ((pTemp = (VObject*)calloc(1, sizeof(VObject))) == NULL) {
917 memset(pTemp, 0, sizeof(VObject));
918 pTemp->property = type;
920 if (pCurrent->pTop == NULL) {
921 pCurrent->pTop = pTemp;
922 pCurrent->pCur = pTemp;
924 pCurrent->pCur->pSibling = pTemp;
925 pCurrent->pCur = pTemp;
932 param_status = false;
936 case VMSG_PARAM_NAME_STATUS:
939 param = __VMsgGetParamName(pMsgRaw, &status, &dLen);
942 if (param_status != true) {
944 if ((pTmpParam = (VParam*)calloc(1, sizeof(VParam))) == NULL)
948 pCurrent->pCur->pParam = pTmpParam;
949 memset(pTmpParam, 0x00, sizeof(VParam));
950 VDATA_TRACE("pTmpParam : %p", pTmpParam);
952 if ((pTmpParam->pNext = (VParam*)calloc(1, sizeof(VParam))) == NULL)
955 pTmpParam = pTmpParam->pNext;
956 memset(pTmpParam, 0x00, sizeof(VParam));
957 VDATA_TRACE("pTmpParam : %p", pTmpParam);
960 pTmpParam->parameter = param;
963 case VMSG_PARAM_VALUE_STATUS:
966 switch (pTmpParam->parameter) {
967 case VMSG_PARAM_TYPE:
968 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
969 numberedParam |= __VMsgGetValue(szValue, pMsgTypeList, VMSG_TYPE_PARAM_NUM);
971 case VMSG_PARAM_VALUE:
972 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
973 numberedParam |= __VMsgGetValue(szValue, pMsgValueList, VMSG_VALUE_PARAM_NUM);
975 case VMSG_PARAM_ENCODING:
976 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
977 numberedParam |= __VMsgGetValue(szValue, pMsgEncList, VMSG_ENCODE_PARAM_NUM);
980 case VMSG_PARAM_CHARSET:
981 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
982 numberedParam |= __VMsgGetValue(szValue, pMsgCharsetList, VMSG_CHARSET_PARAM_NUM);
984 case VMSG_PARAM_CONTEXT:
985 case VMSG_PARAM_LANGUAGE:
986 // prevent 7605 08.03.13
987 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
991 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
993 SET_PARAM_VALUE(numberedParam, szValue, pMsgTypeList, VMSG_TYPE_PARAM_NUM, pTmpParam, VMSG_PARAM_TYPE, enc);
994 SET_PARAM_VALUE(numberedParam, szValue, pMsgValueList, VMSG_VALUE_PARAM_NUM, pTmpParam, VMSG_PARAM_VALUE, enc);
995 SET_PARAM_VALUE(numberedParam, szValue, pMsgEncList, VMSG_ENCODE_PARAM_NUM, pTmpParam, VMSG_PARAM_ENCODING, enc);
996 SET_PARAM_VALUE(numberedParam, szValue, pMsgCharsetList, VMSG_CHARSET_PARAM_NUM, pTmpParam, VMSG_PARAM_CHARSET, enc);
1005 VDATA_TRACE("%d, %s, %p", numberedParam, szValue, pTmpParam);
1006 pTmpParam->paramValue = numberedParam;
1007 pTmpParam->pNext = NULL;
1011 case VMSG_TYPE_VALUE_STATUS:
1013 temp = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, pCurrent->pCur);
1015 if (valueCount <= VDATA_VALUE_COUNT_MAX) {
1016 pCurrent->pCur->pszValue[valueCount] = temp;
1018 pCurrent->pCur->valueCount = valueCount;
1019 VDATA_TRACE("object property: %d, value: %s", pCurrent->pCur->property, pCurrent->pCur->pszValue[valueCount - 1]);
1027 VDATA_TRACE("pMsgRawTmp: %s", pMsgRawTmp);
1028 //VFREE(pMsgRawTmp);
1030 if (pVMsg->pTop == NULL) {
1031 VDATA_TRACE("pVMsg->Top: NULL");
1036 VDATA_TRACE("vmsg_ended: false");
1047 vmsg_free_vtree_memory(pVMsg);
1053 * vmsg_encode() compares the string and vMsg type, parameter value.
1055 * @param pVMsgRaw Data which will be encoded
1056 * @return char * Encoded result
1058 char* vmsg_encode(VTree *pVMsgRaw)
1061 char* pVMsgRes = NULL;
1062 char* pTmpVMsgRes = NULL;
1063 VTree* pTmpTree = NULL;
1064 VObject * pTmpObj = NULL;
1070 for (; cnt < pVMsgRaw->pTop->valueCount; cnt++) {
1072 if (pVMsgRaw->pTop->pszValue[cnt] == NULL) {
1073 VDATA_TRACE("pVMsgRaw->pTop->valueCount : %d", pVMsgRaw->pTop->valueCount);
1074 VDATA_TRACE("pVMsgRaw->pTop->pszValue[%d] : %s", cnt, pVMsgRaw->pTop->pszValue[cnt]);
1080 pTmpTree = pVMsgRaw;
1081 pTmpObj = pVMsgRaw->pTop;
1084 switch (pTmpTree->treeType) {
1091 if ((pVMsgRes = (char *)calloc(1, sizeof(char) * (total += 13))) == NULL) {
1092 VDATA_TRACE("vmsg_encode:calloc failed\n");
1096 memcpy(pVMsgRes, "BEGIN:VMSG\r\n", 13);
1100 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, sizeof(char) * (total += 14))) == NULL) {
1101 VDATA_TRACE("vmsg_encode:realloc failed\n");
1107 pVMsgRes = pTmpVMsgRes;
1108 g_strlcat(pVMsgRes, "BEGIN:VBODY\r\n", 13);
1116 if (pTmpObj == NULL)
1119 if ((pTemp = __VMsgTypeEncode(pTmpObj, pTmpObj->property == VCARD_TYPE_TEL ? "TEL" : pszMsgTypeList[pTmpObj->property])) != NULL) {
1120 if (pTmpTree->treeType == VCARD) {
1121 char* encoded = NULL;
1123 encoded = vcard_encode(pTmpTree);
1124 if (encoded == NULL) {
1125 VDATA_TRACE("vcard_encode() failed\n");
1132 len = strlen(encoded);
1134 if ((pTmpVMsgRes = (char*)realloc(pVMsgRes, (total += len+10))) == NULL) {
1135 VDATA_TRACE("vmsg_encode():realloc failed\n");
1143 pVMsgRes = pTmpVMsgRes;
1144 g_strlcat(pVMsgRes, encoded, len+10);
1145 VDATA_TRACE("pTemp : %s", encoded);
1150 len = strlen(pTemp);
1152 if ((pTmpVMsgRes = (char*)realloc(pVMsgRes, (total += len+10))) == NULL) {
1153 VDATA_TRACE("vmsg_encode():realloc failed\n");
1159 pVMsgRes = pTmpVMsgRes;
1160 g_strlcat(pVMsgRes, pTemp, len+10);
1161 VDATA_TRACE("pTemp : %s", pTemp);
1164 if (pTmpObj->pSibling != NULL)
1165 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;
1259 char* pEncode = NULL;
1264 len = strlen(pType);
1265 biLen = pTypeObj->numOfBiData;
1267 if ((szTypeValue = (char *)calloc(1, total += (len+1))) == NULL) {
1268 VDATA_TRACE("__VMsgTypeEncode():calloc failed\n");
1272 memset(szTypeValue, '\0', (len+1));
1273 g_strlcat(szTypeValue, pType, len+1);
1275 pTemp = __VMsgParamEncode(pTypeObj, &enc);
1276 if (pTemp != NULL) {
1277 len = strlen(pTemp);
1278 if ((szTypeValue = (char *)realloc(szTypeValue, (total += len))) == NULL) {
1279 VDATA_TRACE("__VMsgTypeEncode():realloc failed\n");
1285 g_strlcat(szTypeValue, pTemp, len);
1290 if ((szTypeValue = (char *)realloc(szTypeValue, (total += 2))) == NULL) {
1295 g_strlcat(szTypeValue, ":", 2);
1299 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1300 for (i = 0; i < pTypeObj->valueCount; i++) {
1302 if (pTypeObj->pszValue[i] != NULL)
1303 len += strlen(pTypeObj->pszValue[i]);
1309 for (i = 0; i < pTypeObj->valueCount; i++) {
1312 if ((pEncode = (char *)calloc(1, len+20)) == NULL) {
1318 memset(pEncode, '\0', len+20);
1320 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1321 g_strlcat(pEncode, pTypeObj->pszValue[i], 20);
1324 memcpy(pEncode, pTypeObj->pszValue[i], biLen);
1327 strncpy(buf, pTypeObj->pszValue[i], 999);
1329 g_strlcat(pEncode, ";" , len+20);
1330 g_strlcat(pEncode, buf , len+20);
1334 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1336 g_strlcat(pEncode, "\0\0", 2);
1337 len = strlen(pEncode);
1343 if (enc & pMsgEncList[2].flag) {
1344 if ((pRes = (char *)calloc(1, len * 6 + 10)) == NULL) {
1351 _VQPEncode(pRes, pEncode);
1353 } else if (enc & pMsgEncList[1].flag) {
1354 if ((pRes = (char *)calloc(1, (len * 8 / 6) + 48)) == NULL) {
1361 memset(pRes, '\0', ((len * 8 / 6) + 48));
1362 _VB64Encode(pRes, pEncode, biLen);
1363 VDATA_TRACE("Origin Size: %d, Allocated Size %d, Coverted Size: %d\n", biLen, (len * 8 / 6) + 48, strlen(pRes));
1366 if ((pRes = (char *)calloc(1, len+30)) == NULL) {
1372 memset(pRes, '\0', (len + 30));
1374 memcpy(pRes, pEncode, len);
1379 if ((pRes = (char *)realloc(pRes, strlen(pRes) + 3)) == NULL) {
1385 g_strlcat(pRes, "\r\n", strlen(pRes) + 2);
1389 if ((szTypeValue = (char *)realloc(szTypeValue, (total += (len+3)))) == NULL) {
1396 g_strlcat(szTypeValue, pRes, total - 1);
1398 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1399 _VRLSpace(szTypeValue);
1400 _VRTSpace(szTypeValue);
1410 * __VMsgParamEncode() Parameter Encoding.
1412 * @param pTypeObj Data which will be encoded
1413 * @param pEnc Name of the type
1416 __VMsgParamEncode(VObject* pTypeObj, int* pEnc)
1424 char* szParam = NULL;
1425 VParam* pTemp = NULL;
1426 ValueObj* pList = NULL;
1428 /** Paramter initialize. */
1429 pTemp = pTypeObj->pParam;
1431 /** Momory Allocation for parameter string. */
1432 if (pTemp != NULL) {
1433 if ((szParam = (char*)calloc(1, len += 2)) == NULL) {
1437 memset(szParam, 0x00, 2);
1440 /** appending pamaters. */
1443 if (pTemp == NULL) break;
1447 /** Expand szParam string. For appending.*/
1448 if ((szParam = (char *)realloc(szParam, len += 15)) == NULL) {
1453 /** appending paramter name. */
1454 g_strlcat(szParam, ";" , len);
1455 if (pTemp->parameter != VMSG_PARAM_TYPE) {
1456 g_strlcat(szParam, pszMsgParamList[pTemp->parameter], len);
1457 g_strlcat(szParam, "=", len);
1460 /** Set Parameter Value name. */
1461 switch (pTemp->parameter) {
1462 case VMSG_PARAM_ENCODING:
1463 *pEnc = pMsgEncList[pTemp->paramValue].flag;
1464 shift = VMSG_ENCODE_PARAM_NUM;
1465 pList = pMsgEncList; bSupported = true;
1467 case VMSG_PARAM_TYPE:
1468 shift = VMSG_TYPE_PARAM_NUM;
1469 pList = pMsgTypeList; bSupported = true;
1471 case VMSG_PARAM_VALUE:
1472 shift = VMSG_VALUE_PARAM_NUM;
1473 pList = pMsgValueList; bSupported = true;
1475 case VMSG_PARAM_CHARSET:
1476 shift = VMSG_CHARSET_PARAM_NUM;
1477 pList = pMsgCharsetList; bSupported = true;
1480 if ((szParam = (char*)realloc(szParam, 5)) == NULL) {
1484 g_strlcat(szParam, "NONE", strlen("NONE"));
1487 /** exchage parameter value's to string.*/
1488 if (bSupported == true) {
1490 for (i = 0, sNum = 0x00000001; i < shift; i++) {
1492 if (pList[pTemp->paramValue].flag & sNum) {
1493 if ((szParam = (char *)realloc(szParam, (len += (strlen(pList[i].szName) + 2)))) == NULL) {
1498 g_strlcat(szParam, pList[i].szName, len);
1499 g_strlcat(szParam, "; ", len);
1506 /** remove semicolon from tail. */
1507 for (i = strlen(szParam); i > 0 ; i--) {
1509 if (szParam[i] == ' ' && szParam[i-1] == ';') {
1510 szParam[i-1] = '\0';
1515 if (pTemp->pNext != NULL)
1516 pTemp = pTemp->pNext;
1525 vmsg_free_vtree_memory(VTree * pTree)
1528 if (pTree == NULL) {
1533 return __VMsgFreeVTreeMemory(pTree);