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.
21 #define VCARD_TYPE_NUM 34
22 #define VCAL_TYPE_NUM 66
23 #define VMSG_TYPE_NUM 12
24 extern char *pszCardTypeList[];
27 char Base64Table[65] = { 'A',
28 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
29 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
30 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e',
31 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
32 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y',
33 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
37 /* Function Declaration */
38 int __VFindBase64(char);
39 int __VBase64Check(char *);
40 int __VRepChar2Space(char *, char);
41 char __VHexaDecoder(char *);
42 void __VHexaEncoder(char *);
43 int __VIsPrintable(char);
47 * vCardIsSpace() returns one if char is either a space, tab, or newline.
49 * @param s1 [in] pointer to first string.
50 * @param s2 [in] pointer to second string.
51 * @return 1 'in' is a space character.
52 * @return 0 'in' is not a space.
57 if ((in == TAB) || (in == WSP))
65 * vRemLeadSpace() removes leading space in string 'in'.
67 * @param in [inout] pointer to string.
68 * @return 0 if success.
79 while (!done && in[i]) {
97 * vRemTermSpace() removes terminating space.
99 * @param in [inout] pointer to string.
100 * @return 0 if success.
111 while (!done && !(i < 0)) {
112 if (_VIsSpace(in[i]))
123 * VUnescape() unescapes escaped character.
125 * @param in [inout] pointer to string.
126 * @return 0 if success.
139 for (i = 0, index = 0; i < len; i++) {
144 if (c2 == ';') continue;
155 * VEscape() escapes character.
157 * @param in [inout] pointer to string.
158 * @return 0 if success.
170 buf = (char*) calloc(1, len*2+1);
172 for (i = 0, index = 0; i < len; i++) {
180 strncpy(in, buf, len*2+1);
190 * vManySpace2Space() converts multiple spaces to single space in 'in'.
192 * @param in [inout] pointer to string.
193 * @return int length of converted string.
196 _VManySpace2Space(char *in)
202 for (i = 0; in[i]; i++) {
203 if (_VIsSpace(in[i])) {
224 * vFindBase64() returns the integer repesentation of the location in base64 table.
226 * @param in a character
227 * @return int The base64 table location of input character
230 __VFindBase64(char in)
234 for (i = 0; i < 65; i++) {
235 if (Base64Table[i] == in)
244 * vBase64Check() returns the total length of input except non-base64 value.
246 * @param in char values which are base64 or non-base64
247 * @return int the total length of input except non-base64
250 __VBase64Check(char *in)
256 base = __VFindBase64(in[i]);
271 * vBase64Decoder() decodes the base64 encoded input.
273 * @param Src Base64 encoded input
274 * @param Dest The destination buffer of decoded value
275 * @return int The total length decoded value
278 _VB64Decode(char *Dest, char *Src)
285 char Debuffer[4] = {0x00, 0x00, 0x00, '\0'};
289 len = __VBase64Check(Src);
291 VDATA_TRACE("total length of Src except non-base64 value = %d", len);
294 for (i = 0; i < 3; i++)
297 for (i = 0; i < 4; i++, Encoded++, j++) {
298 if (*Encoded == 0x00) break;
299 if ((res = __VFindBase64(*Encoded)) < 0) continue;
311 DecodeTemp = Base << 2;
312 Debuffer[0] |= DecodeTemp;
315 DecodeTemp = Base >> 4;
316 Debuffer[0] |= DecodeTemp;
317 DecodeTemp = Base << 4;
318 Debuffer[1] |= DecodeTemp;
321 DecodeTemp = Base >> 2;
322 Debuffer[1] |= DecodeTemp;
323 DecodeTemp = Base << 6;
324 Debuffer[2] |= DecodeTemp;
328 Debuffer[2] |= DecodeTemp;
338 Dest[index] = Debuffer[0];
342 Dest[index++] = Debuffer[0];
343 Dest[index++] = Debuffer[1];
347 Dest[index++] = Debuffer[0];
348 Dest[index++] = Debuffer[1];
349 Dest[index++] = Debuffer[2];
358 * vBase64Encoder() encode the input to base64.
360 * @param Src non-base64 char input
361 * @param Dest The destination buffer of encoded value
365 _VB64Encode(char *Dest, char *Src, int len)
367 char* Encoded = Dest;
372 int base1 = 0, base2 = 0;
373 char Enbuffer[4] = {0,};
374 char Debuffer[3] = {0,};
377 for (i = 0; i < 4; i++)
380 for (i = 0; i < len; i++) {
385 Debuffer[0] = *Decoded;
388 Debuffer[1] = *Decoded;
391 Debuffer[2] = *Decoded;
392 index = (int)((Debuffer[0] & 0xFC) >> 2);
393 Enbuffer[0] = Base64Table[index];
394 base1 = (int)((Debuffer[0] & 0x03) << 4);
395 base2 = (int)((Debuffer[1] & 0xF0) >> 4);
396 index = (int)(base1 | base2);
397 Enbuffer[1] = Base64Table[index];
398 base1 = (int)((Debuffer[1] & 0x0F) << 2);
399 base2 = (int)((Debuffer[2] & 0xC0) >> 6);
400 index = (int)(base1 | base2);
401 Enbuffer[2] = Base64Table[index];
402 index = (int)(Debuffer[2] & 0x3F);
403 Enbuffer[3] = Base64Table[index];
405 Encoded[length++] = Enbuffer[0];
406 Encoded[length++] = Enbuffer[1];
407 Encoded[length++] = Enbuffer[2];
408 Encoded[length++] = Enbuffer[3];
410 for (j = 0; j < 3; j++)
425 index = (int)((Debuffer[0] & 0xFC) >> 2);
426 Enbuffer[0] = Base64Table[index];
427 base1 = (int)((Debuffer[0] & 0x03) << 4);
428 base2 = (int)((Debuffer[1] & 0xF0) >> 4);
429 index = (int)(base1 | base2);
430 Enbuffer[1] = Base64Table[index];
431 Enbuffer[2] = Base64Table[64];
432 Enbuffer[3] = Base64Table[64];
434 Encoded[length++] = Enbuffer[0];
435 Encoded[length++] = Enbuffer[1];
436 Encoded[length++] = Enbuffer[2];
437 Encoded[length++] = Enbuffer[3];
441 index = (int)((Debuffer[0] & 0xFC) >> 2);
442 Enbuffer[0] = Base64Table[index];
443 base1 = (int)((Debuffer[0] & 0x03) << 4);
444 base2 = (int)((Debuffer[1] & 0xF0) >> 4);
445 index = (int)(base1 | base2);
446 Enbuffer[1] = Base64Table[index];
447 base1 = (int)((Debuffer[1] & 0x0F) << 2);
448 base2 = (int)((Debuffer[2] & 0xC0) >> 6);
449 index = (int)(base1 | base2);
450 Enbuffer[2] = Base64Table[index];
451 Enbuffer[3] = Base64Table[64];
453 Encoded[length++] = Enbuffer[0];
454 Encoded[length++] = Enbuffer[1];
455 Encoded[length++] = Enbuffer[2];
456 Encoded[length++] = Enbuffer[3];
461 Encoded[length] = '\0';
469 __VRepChar2Space(char *vRaw, char replaced)
474 if (*vRaw == replaced)
486 * vUnfolding() unfold the folded line.
488 * @param string The folded line input
489 * @return int Total length of unfolded output
492 _VUnfolding(char *string)
497 len = strlen(string);
499 for (i = 0, j = 0; i < len; i++, j++) {
500 string[j] = string[i];
502 /* 12.03.2004 Process garbage character at the end of vcard/vcal */
503 if (_VIsSpace(string[i]) && (i < len-5)) {
504 if (i >= 1 && (string[i-1] == LF || string[i-1] == CR)) {
513 if (i >= 2 && (string[i-2] == LF || string[i-2] == CR)) {
531 __VIsNewType(char *pCardRaw)
533 int count = 0, i = 0, low = 0, high = 0, diff = 0;
534 char strTypeName[50] = {0};
537 if (*pCardRaw == CR || *pCardRaw == LF)
540 if (*pCardRaw == ';' || *pCardRaw == ':' || count >= 50)
543 strTypeName[count++] = *pCardRaw++;
549 for (low = 0, high = VCARD_TYPE_NUM - 1; high >= low; diff < 0 ? (low = i+1) : (high = i-1)) {
550 i = (low + high) / 2;
551 diff = strcmp(pszCardTypeList[i], strTypeName);
552 if (diff == 0) /* success: found it */
559 /* res = __VCardGetName(strTypeName, (char**)pszCardTypeList, VCARD_TYPE_NUM); */
564 __VIsNewTypeforOrg(char *pCardRaw, int vType)
566 int count = 0, i = 0, low = 0, high = 0, diff = 0, vTypeNum;
567 char strTypeName[50] = {0};
568 extern char* pszCardTypeList[];
569 extern char* pszMsgTypeList[];
572 if (*pCardRaw == CR || *pCardRaw == LF)
575 if (*pCardRaw == ';' || *pCardRaw == ':' || count >= 50)
578 strTypeName[count++] = *pCardRaw++;
583 vTypeNum = VCARD_TYPE_NUM;
584 else if (vType == VMESSAGE)
585 vTypeNum = VMSG_TYPE_NUM;
589 for (low = 0, high = vTypeNum - 1; high >= low; diff < 0 ? (low = i+1) : (high = i-1)) {
590 i = (low + high) / 2;
593 diff = strcmp(pszCardTypeList[i], strTypeName);
594 else if (vType == VMESSAGE)
595 diff = strcmp(pszMsgTypeList[i], strTypeName);
597 if (diff == 0) /* success: found it */
599 else if (!strncmp(strTypeName, "X-", 2))
603 /* if (count <= 50) return TRUE; */
607 /* res = __VCardGetName(strTypeName, (char**)pszCardTypeList, VCARD_TYPE_NUM); */
611 _VUnfoldingNoSpecNew(char *string)
618 len = strlen(string);
620 if (!(newString = (char*) calloc(1, len+1)))
623 for (i = 0, j = 0; i < len; i++, j++) {
625 newString[j] = string[i];
629 if (string[i] == '=') {
631 if (string[i+1] == CR && string[i+2] == LF) {
633 if (__VIsNewType(string) == false) {
640 } else if (string[i+1] == CR || string[i+1] == LF) {
641 if (__VIsNewType(string) == false) {
649 } else if (string[i] == ' ') {
651 if (i >= 2 && string[i-2] == CR && string[i-1] == LF) {
652 if (__VIsNewType(string) == false) {
660 } else if (i >= 1 && (string[i-1] == CR || string[i-1] == LF)) {
666 } else if ((string[i] == CR || string[i] == LF) && __VIsNewType(string) == false) {
668 if (string[i+1] == LF) {
685 * vUnfolding() unfold the folded line.
687 * @param string The folded line input
688 * @return int Total length of unfolded output
691 _VUnfoldingNoSpec(char *string, int vType)
696 len = strlen(string);
698 for (i = 0, j = 0; i < len; i++, j++) {
699 string[j] = string[i];
702 if (string[i] == '=') {
703 if (string[i+1] == CR && string[i+2] == LF && string[i+3] == '=') {
710 } else if (string[i+1] == CR && string[i+2] == LF && __VIsNewTypeforOrg(&string[i+3], vType) == false) {
718 } else if (string[i] == WSP || string[i] == TAB) {
719 if (i >= 2 && string[i-2] == CR && string[i-1] == LF) {
727 } else if (i >= 1 && (string[i-1] == CR || string[i-1] == LF)) {
747 * vFolding() decodes the base64 encoded input.
749 * @param contentline Original line (unfolded)
750 * @param Dest The destination buffer of folded result
753 _VFolding(char *result, char *contentline)
757 while (*contentline) {
765 *result++ = *contentline++;
774 * vFolding() decodes the base64 encoded input.
776 * @param contentline Original line (unfolded)
777 * @param Dest The destination buffer of folded result
780 _VFoldingQP(char *result, char *contentline)
784 while (*contentline) {
792 *result++ = *contentline++;
801 * vFolding() decodes the base64 encoded input.
803 * @param contentline Original line (unfolded)
804 * @param Dest The destination buffer of folded result
807 _VFoldingNoSpace(char *result, char *contentline)
811 while (*contentline) {
818 *result++ = *contentline++;
827 * vQuotedPrintalbeDecoder() decodes the quoted-printable encoded input.
829 * @param Src Quoted-printable encoded input
830 * @return int The total length decoded value
833 _VQPDecode(char *src)
841 if (!(_VIsSpace(src[i + 1]) || (src[i + 1] == '\r') || (src[i+1] == '\n'))) {
842 if (src[i + 1] == '0' && (src[i + 2] == 'D' || src[i +2] == 'd') && src[i + 3] == '='
843 && src[i + 4] == '0' && (src[i + 5] == 'A' || src[i + 5] == 'a')) {
850 decodedNum = __VHexaDecoder(qp);
865 j = _VManySpace2Space(src);
873 * vQuotedPrintableEncoder() decodes the quoted-printalbe encoded input.
875 * @param Src Quoted-printable encoded input
876 * @param Dest The destination buffer of decoded value
877 * @return int The total length decoded value
880 _VQPEncode(char *dest, char *src)
882 int i = 0, j = 0, k = 0;
883 char encoded[2] = {0x0f, 0x0f};
885 while (src[i] /*&& (src[i] > 0)*/) {
886 if (k == 73 && _VIsSpace(src[i])) {
888 dest[j++] = '='; dest[j++] = '2'; dest[j++] = '0';
890 } else if (src[i] == TAB) {
891 dest[j++] = '='; dest[j++] = '0'; dest[j++] = '9';
894 /*} else if (k == 76) {
895 dest[j++] = '='; dest[j++] = WSP;
898 } else if (!__VIsPrintable(src[i])) {
900 encoded[0] &= (src[i] >> 4);
901 encoded[1] &= (src[i]);
902 __VHexaEncoder(encoded);
903 dest[j++] = encoded[0]; encoded[0] = 0x0f;
904 dest[j++] = encoded[1]; encoded[1] = 0x0f;
906 } else if (src[i] == '\r' || src[i] == '\n') {
907 dest[j++] = '='; dest[j++] = '0'; dest[j++] = 'D'; k += 3;
908 dest[j++] = '='; dest[j++] = '0'; dest[j++] = 'A'; k += 3;
910 dest[j++] = src[i]; k++;
922 * vIsPrintable() check whether the input is printable.
925 * @return true/false if input is printable :true else : false
928 __VIsPrintable(char in)
930 if (in >= 33 && in <= 60) return true;
931 else if (in >= 62 && in <= 126) return true;
932 else if (in == WSP || in == TAB) return true;
933 else if (in == '\r' || in == '\n') return true;
940 * vHexaDecoder() output the character value of inputed hexadecimal value.
942 * @param qp Hexadecimal input value
943 * @return char Character representation of input hexadecimal value
946 __VHexaDecoder(char *qp)
949 char decoded[2] = {0x00, 0x00};
952 for (i = 0; i < 2; i++) {
1011 res = (char)((decoded[0] << 4) + decoded[1]);
1019 * vHexaEncoder() output the hexadecimal value of input character value.
1021 * @return qp Character representation of input hexadecimal value
1024 __VHexaEncoder(char *qp)
1028 for (i = 0; i < 2; i++) {
1084 * _VIsCrLf() returns one if char is either a space, tab, or newline.
1086 * @param s1 [in] pointer to first string.
1087 * @param s2 [in] pointer to second string.
1088 * @return 1 'in' is a space character.
1089 * @return 0 'in' is not a space.
1094 if ((in == CR) || (in == LF))
1101 * vManySpace2Space() converts multiple spaces to single space in 'in'.
1103 * @param in [inout] pointer to string.
1104 * @return int length of converted string.
1107 _VManyCRLF2CRLF(char *pIn)
1110 bool bCrLf = false, bFirstCrLf = true;
1113 for (i = 0; pIn[i]; i++) {
1114 if (_VIsCrLf(pIn[i]) && _VIsCrLf(pIn[i+1])) {
1115 if (bFirstCrLf && !bCrLf) {
1117 } else if (!bFirstCrLf) {