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] : %d, list[%d].szName : %p", i, size, i, list[i].flag, 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 ==> %d", pCurParam->parameter);
468 VDATA_TRACE("pVALUE ==> %d", 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;
847 dLen = ((strstr(pMsgRaw, "END:VCARD") + 9) - pMsgRaw);
850 if (!strncmp(szMsgBegin, "VMSG", strlen("VMSG"))) {
851 if ((pVMsg = (VTree*)calloc(1, sizeof(VTree))) == NULL)
853 memset(pVMsg, 0x00, sizeof(VTree));
855 pVMsg->treeType = VMESSAGE;
860 } else if (!strncmp(szMsgBegin, "VBODY", strlen("VBODY"))) {
861 if ((pVBody = (VTree*)calloc(1, sizeof(VTree))) == NULL)
864 memset(pVBody, 0x00, sizeof(VTree));
865 pVBody->treeType = VBODY;
868 pVBody->pNext = NULL;
870 pCurrent->pNext = pVBody;
881 /* szMsgBegin = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, NULL); */
883 if (!strncmp(pMsgRaw, "VMSG", strlen("VMSG"))) {
887 status = VMSG_TYPE_NAME_STATUS;
888 /* pMsgRaw += dLen; */
890 VDATA_TRACE("pMsgRaw:%s", pMsgRaw);
898 if (UNKNOWN_NAME == type || type < 0) {
899 status = VMSG_TYPE_NAME_STATUS;
903 if ((pTemp = (VObject*)calloc(1, sizeof(VObject))) == NULL)
905 pTemp->property = type;
908 if (pCurrent->pTop == NULL) {
909 pCurrent->pTop = pTemp;
910 pCurrent->pCur = pTemp;
912 pCurrent->pCur->pSibling = pTemp;
913 pCurrent->pCur = pTemp;
924 param_status = false;
928 case VMSG_PARAM_NAME_STATUS:
931 param = __VMsgGetParamName(pMsgRaw, &status, &dLen);
934 if (param_status != true) {
935 if ((pTmpParam = (VParam*)calloc(1, sizeof(VParam))) == NULL)
939 pCurrent->pCur->pParam = pTmpParam;
942 VDATA_TRACE("pCurrent is NULL");
945 VDATA_TRACE("pTmpParam : %p", pTmpParam);
947 if ((pTmpParam->pNext = (VParam*)calloc(1, sizeof(VParam))) == NULL)
950 pTmpParam = pTmpParam->pNext;
951 VDATA_TRACE("pTmpParam : %p", pTmpParam);
954 pTmpParam->parameter = param;
957 case VMSG_PARAM_VALUE_STATUS:
960 if (param_status != true) {
961 VDATA_TRACE("Inavalid status(param)");
965 switch (pTmpParam->parameter) {
966 case VMSG_PARAM_TYPE:
967 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
968 numberedParam |= __VMsgGetValue(szValue, pMsgTypeList, VMSG_TYPE_PARAM_NUM);
970 case VMSG_PARAM_VALUE:
971 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
972 numberedParam |= __VMsgGetValue(szValue, pMsgValueList, VMSG_VALUE_PARAM_NUM);
974 case VMSG_PARAM_ENCODING:
975 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
976 numberedParam |= __VMsgGetValue(szValue, pMsgEncList, VMSG_ENCODE_PARAM_NUM);
979 case VMSG_PARAM_CHARSET:
980 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
981 numberedParam |= __VMsgGetValue(szValue, pMsgCharsetList, VMSG_CHARSET_PARAM_NUM);
983 case VMSG_PARAM_CONTEXT:
984 case VMSG_PARAM_LANGUAGE:
985 /* prevent 7605 08.03.13 */
986 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
990 szValue = __VMsgGetParamVal(pMsgRaw, &status, &dLen);
992 SET_PARAM_VALUE(numberedParam, szValue, pMsgTypeList, VMSG_TYPE_PARAM_NUM, pTmpParam, VMSG_PARAM_TYPE, enc);
993 SET_PARAM_VALUE(numberedParam, szValue, pMsgValueList, VMSG_VALUE_PARAM_NUM, pTmpParam, VMSG_PARAM_VALUE, enc);
994 SET_PARAM_VALUE(numberedParam, szValue, pMsgEncList, VMSG_ENCODE_PARAM_NUM, pTmpParam, VMSG_PARAM_ENCODING, enc);
995 SET_PARAM_VALUE(numberedParam, szValue, pMsgCharsetList, VMSG_CHARSET_PARAM_NUM, pTmpParam, VMSG_PARAM_CHARSET, enc);
1004 VDATA_TRACE("%d, %s, %p", numberedParam, szValue, pTmpParam);
1005 pTmpParam->paramValue = numberedParam;
1006 pTmpParam->pNext = NULL;
1010 case VMSG_TYPE_VALUE_STATUS:
1012 temp = __VMsgGetTypeVal(pMsgRaw, &status, &dLen, enc, pCurrent->pCur);
1014 if (valueCount < VDATA_VALUE_COUNT_MAX) {
1015 pCurrent->pCur->pszValue[valueCount] = temp;
1017 pCurrent->pCur->valueCount = valueCount;
1018 VDATA_TRACE("object property: %d, value: %s", pCurrent->pCur->property, pCurrent->pCur->pszValue[valueCount - 1]);
1026 VDATA_TRACE("pMsgRawTmp: %s", pMsgRawTmp);
1027 /* VFREE(pMsgRawTmp); */
1029 if (pVMsg && pVMsg->pTop == NULL) {
1030 VDATA_TRACE("pVMsg->Top: NULL");
1035 VDATA_TRACE("vmsg_ended: false");
1049 vmsg_free_vtree_memory(pVMsg);
1055 * vmsg_encode() compares the string and vMsg type, parameter value.
1057 * @param pVMsgRaw Data which will be encoded
1058 * @return char * Encoded result
1060 char* vmsg_encode(VTree *pVMsgRaw)
1063 char* pVMsgRes = NULL;
1064 char* pTmpVMsgRes = NULL;
1065 VTree* pTmpTree = NULL;
1066 VObject * pTmpObj = NULL;
1072 if (!pVMsgRaw || !pVMsgRaw->pTop)
1075 for (; cnt < pVMsgRaw->pTop->valueCount; cnt++) {
1076 if (pVMsgRaw->pTop->pszValue[cnt] == NULL) {
1077 VDATA_TRACE("pVMsgRaw->pTop->valueCount : %d", pVMsgRaw->pTop->valueCount);
1078 VDATA_TRACE("pVMsgRaw->pTop->pszValue[%d] : %s", cnt, pVMsgRaw->pTop->pszValue[cnt]);
1084 pTmpTree = pVMsgRaw;
1085 pTmpObj = pVMsgRaw->pTop;
1088 switch (pTmpTree->treeType) {
1095 if ((pVMsgRes = (char *)calloc(1, sizeof(char) * (total += 13))) == NULL) {
1096 VDATA_TRACE("vmsg_encode:calloc failed\n");
1100 memcpy(pVMsgRes, "BEGIN:VMSG\r\n", 13);
1104 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, sizeof(char) * (total += 14))) == NULL) {
1105 VDATA_TRACE("vmsg_encode:realloc failed\n");
1111 pVMsgRes = pTmpVMsgRes;
1112 g_strlcat(pVMsgRes, "BEGIN:VBODY\r\n", 13);
1120 if (pTmpObj == NULL)
1123 if ((pTemp = __VMsgTypeEncode(pTmpObj, pTmpObj->property == VCARD_TYPE_TEL ? "TEL" : pszMsgTypeList[pTmpObj->property])) != NULL) {
1124 if (pTmpTree->treeType == VCARD) {
1125 char* encoded = NULL;
1127 encoded = vcard_encode(pTmpTree);
1128 if (encoded == NULL) {
1129 VDATA_TRACE("vcard_encode() failed\n");
1136 len = strlen(encoded);
1138 if ((pTmpVMsgRes = (char*)realloc(pVMsgRes, (total += len+10))) == NULL) {
1139 VDATA_TRACE("vmsg_encode():realloc failed\n");
1147 pVMsgRes = pTmpVMsgRes;
1148 g_strlcat(pVMsgRes, encoded, len+10);
1149 VDATA_TRACE("pTemp : %s", encoded);
1154 len = strlen(pTemp);
1156 if ((pTmpVMsgRes = (char*)realloc(pVMsgRes, (total += len+10))) == NULL) {
1157 VDATA_TRACE("vmsg_encode():realloc failed\n");
1163 pVMsgRes = pTmpVMsgRes;
1164 g_strlcat(pVMsgRes, pTemp, len+10);
1165 VDATA_TRACE("pTemp : %s", pTemp);
1168 if (pTmpObj->pSibling != NULL)
1169 pTmpObj = pTmpObj->pSibling;
1176 switch (pTmpTree->treeType) {
1178 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, (total += 12))) == NULL) {
1180 VDATA_TRACE("vcal_encode():realloc failed\n");
1184 pVMsgRes = pTmpVMsgRes;
1185 g_strlcat(pVMsgRes, "END:VBODY\r\n", 12);
1196 if (pTmpTree->pNext != NULL)
1197 pTmpTree = pTmpTree->pNext;
1200 pTmpObj = pTmpTree->pTop;
1203 if ((pTmpVMsgRes = (char *)realloc(pVMsgRes, (total += 11))) == NULL) {
1204 VDATA_TRACE("vmsg_encode:realloc failed\n");
1210 pVMsgRes = pTmpVMsgRes;
1211 g_strlcat(pVMsgRes, "END:VMSG\r\n", 11);
1218 * VIsVmsgFile() verify VMsg file.
1220 * @param pVMsgRaw Data which will be encoded
1221 * @return int result (true or false)
1224 __VIsVmsgFile(char *pMsgRaw, int mode)
1227 bool rtnValue = true;
1228 char *pszVmsgBegin = "BEGIN:VMSG";
1230 if (pMsgRaw == NULL)
1235 for (i = 0; i < 10; i++)
1236 if (*pszVmsgBegin++ != *pMsgRaw++) {
1251 * vMsgTypeEncoder() compares the string and vMsg type, parameter value.
1253 * @param typeObj Data which will be encoded
1254 * @param type Name of the type
1255 * @return char * Encoded result
1258 __VMsgTypeEncode(VObject *pTypeObj, char *pType)
1263 char* szTypeValue = NULL;
1264 char* szTemp = NULL;
1267 char* pEncode = NULL;
1272 len = strlen(pType);
1273 biLen = pTypeObj->numOfBiData;
1275 if ((szTypeValue = (char *)calloc(1, total += (len+1))) == NULL) {
1276 VDATA_TRACE("__VMsgTypeEncode():calloc failed\n");
1280 memset(szTypeValue, '\0', (len+1));
1281 g_strlcat(szTypeValue, pType, len+1);
1283 pTemp = __VMsgParamEncode(pTypeObj, &enc);
1284 if (pTemp != NULL) {
1285 len = strlen(pTemp);
1286 if ((szTemp = (char *)realloc(szTypeValue, (total += len))) == NULL) {
1287 VDATA_TRACE("__VMsgTypeEncode():realloc failed\n");
1294 szTypeValue = szTemp;
1296 g_strlcat(szTypeValue, pTemp, len);
1301 if ((szTemp = (char *)realloc(szTypeValue, (total += 2))) == NULL) {
1306 szTypeValue = szTemp;
1309 g_strlcat(szTypeValue, ":", 2);
1313 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1314 for (i = 0; i < pTypeObj->valueCount; i++) {
1316 if (pTypeObj->pszValue[i] != NULL)
1317 len += strlen(pTypeObj->pszValue[i]);
1323 for (i = 0; i < pTypeObj->valueCount; i++) {
1326 if ((pEncode = (char *)calloc(1, len+20)) == NULL) {
1332 memset(pEncode, '\0', len+20);
1334 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1335 g_strlcat(pEncode, pTypeObj->pszValue[i], 20);
1338 memcpy(pEncode, pTypeObj->pszValue[i], biLen);
1341 strncpy(buf, pTypeObj->pszValue[i], 999);
1343 g_strlcat(pEncode, ";" , len+20);
1344 g_strlcat(pEncode, buf , len+20);
1348 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1350 g_strlcat(pEncode, "\0\0", 2);
1351 len = strlen(pEncode);
1357 if (enc & pMsgEncList[2].flag) {
1358 if ((pRes = (char *)calloc(1, len * 6 + 10)) == NULL) {
1365 _VQPEncode(pRes, pEncode);
1367 } else if (enc & pMsgEncList[1].flag) {
1368 if ((pRes = (char *)calloc(1, (len * 8 / 6) + 48)) == NULL) {
1375 memset(pRes, '\0', ((len * 8 / 6) + 48));
1376 _VB64Encode(pRes, pEncode, biLen);
1377 VDATA_TRACE("Origin Size: %d, Allocated Size %d, Coverted Size: %zu\n", biLen, (len * 8 / 6) + 48, strlen(pRes));
1380 if ((pRes = (char *)calloc(1, len+30)) == NULL) {
1386 memset(pRes, '\0', (len + 30));
1388 memcpy(pRes, pEncode, len);
1393 if ((szTemp = (char *)realloc(pRes, strlen(pRes) + 3)) == NULL) {
1402 g_strlcat(pRes, "\r\n", strlen(pRes) + 2);
1406 if ((szTemp = (char *)realloc(szTypeValue, (total += (len+3)))) == NULL) {
1413 szTypeValue = szTemp;
1416 g_strlcat(szTypeValue, pRes, total - 1);
1418 if (strcmp(pType, pszMsgTypeList[6]) != 0) {
1419 _VRLSpace(szTypeValue);
1420 _VRTSpace(szTypeValue);
1430 * __VMsgParamEncode() Parameter Encoding.
1432 * @param pTypeObj Data which will be encoded
1433 * @param pEnc Name of the type
1436 __VMsgParamEncode(VObject* pTypeObj, int* pEnc)
1444 char* szParam = NULL;
1445 char* szTemp = NULL;
1446 VParam* pTemp = NULL;
1447 ValueObj* pList = NULL;
1449 /** Paramter initialize. */
1450 pTemp = pTypeObj->pParam;
1452 /** Momory Allocation for parameter string. */
1453 if (pTemp != NULL) {
1454 if ((szParam = (char*)calloc(1, len += 2)) == NULL) {
1458 memset(szParam, 0x00, 2);
1461 /** appending pamaters. */
1464 if (pTemp == NULL) break;
1468 /** Expand szParam string. For appending.*/
1469 if ((szTemp = (char *)realloc(szParam, len += 15)) == NULL) {
1477 /** appending paramter name. */
1478 g_strlcat(szParam, ";" , len);
1479 if (pTemp->parameter != VMSG_PARAM_TYPE) {
1480 g_strlcat(szParam, pszMsgParamList[pTemp->parameter], len);
1481 g_strlcat(szParam, "=", len);
1484 /** Set Parameter Value name. */
1485 switch (pTemp->parameter) {
1486 case VMSG_PARAM_ENCODING:
1487 *pEnc = pMsgEncList[pTemp->paramValue].flag;
1488 shift = VMSG_ENCODE_PARAM_NUM;
1489 pList = pMsgEncList; bSupported = true;
1491 case VMSG_PARAM_TYPE:
1492 shift = VMSG_TYPE_PARAM_NUM;
1493 pList = pMsgTypeList; bSupported = true;
1495 case VMSG_PARAM_VALUE:
1496 shift = VMSG_VALUE_PARAM_NUM;
1497 pList = pMsgValueList; bSupported = true;
1499 case VMSG_PARAM_CHARSET:
1500 shift = VMSG_CHARSET_PARAM_NUM;
1501 pList = pMsgCharsetList; bSupported = true;
1504 if ((szTemp = (char*)realloc(szParam, 5)) == NULL) {
1511 g_strlcat(szParam, "NONE", strlen("NONE"));
1514 /** exchage parameter value's to string.*/
1515 if (bSupported == true) {
1517 for (i = 0, sNum = 0x00000001; i < shift; i++) {
1519 if (pList[pTemp->paramValue].flag & sNum) {
1520 if ((szTemp = (char *)realloc(szParam, (len += (strlen(pList[i].szName) + 2)))) == NULL) {
1528 g_strlcat(szParam, pList[i].szName, len);
1529 g_strlcat(szParam, "; ", len);
1536 /** remove semicolon from tail. */
1537 for (i = strlen(szParam); i > 0 ; i--) {
1539 if (szParam[i] == ' ' && szParam[i-1] == ';') {
1540 szParam[i-1] = '\0';
1545 if (pTemp->pNext != NULL)
1546 pTemp = pTemp->pNext;
1555 vmsg_free_vtree_memory(VTree * pTree)
1558 if (pTree == NULL) {
1563 return __VMsgFreeVTreeMemory(pTree);