fix build warning
[platform/core/messaging/msg-service.git] / vobject-engine / VCardCalUtil.c
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17
18 #include "VTypes.h"
19 #include "vobject.h"
20
21 #define VCARD_TYPE_NUM 34
22 #define VCAL_TYPE_NUM   66
23 #define VMSG_TYPE_NUM 12
24 extern char *pszCardTypeList[];
25
26 /* BASE64 TABLE */
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',
34         '9',    '+',    '/',    '='
35 };
36
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);
44
45
46 /**
47  * vCardIsSpace() returns one if char is either a space, tab, or newline.
48  *
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.
53  */
54 int
55 _VIsSpace(char in)
56 {
57         if ((in == TAB) || (in == WSP))
58                 return 1;
59         else
60                 return 0;
61 }
62
63
64 /*
65  * vRemLeadSpace() removes leading space in string 'in'.
66  *
67  * @param      in                 [inout] pointer to string.
68  * @return     0                  if success.
69  */
70 int
71 _VRLSpace(char *in)
72 {
73         int     i, j;
74         short int       done;
75
76         i = 0;
77         done = 0;
78
79         while (!done && in[i]) {
80                 if (_VIsSpace(in[i]))
81                         i++;
82                 else
83                         done = 1;
84         }
85
86         j = 0;
87         while (in[i])
88                 in[j++] = in[i++];
89
90         in[j] = '\0';
91
92         return 0;
93 }
94
95
96 /*
97  * vRemTermSpace() removes terminating space.
98  *
99  * @param      in                 [inout] pointer to string.
100  * @return     0                  if success.
101  */
102 int
103 _VRTSpace(char *in)
104 {
105         int                     i;
106         short int       done;
107
108         i = strlen(in) - 1;
109         done = 0;
110
111         while (!done && !(i < 0)) {
112                 if (_VIsSpace(in[i]))
113                         in[i--] = '\0';
114                 else
115                         done = 1;
116         }
117
118         return(0);
119 }
120
121
122 /*
123  * VUnescape() unescapes escaped character.
124  *
125  * @param      in                 [inout] pointer to string.
126  * @return     0                  if success.
127  */
128 int
129 _VUnescape(char *in)
130 {
131         int                     i;
132         int                     index;
133         int                     len;
134         char c1;
135         char c2;
136
137         len = strlen(in);
138
139         for (i = 0, index = 0; i < len; i++) {
140                 c1 = in[i];
141
142                 if (c1 == '\\') {
143                         c2 = in[i+1];
144                         if (c2 == ';') continue;
145                 }
146                 in[index++] = c1;
147         }
148
149         in[index] = '\0';
150
151         return(0);
152 }
153
154 /*
155  * VEscape() escapes character.
156  *
157  * @param      in                 [inout] pointer to string.
158  * @return     0                  if success.
159  */
160 int
161 _VEscape(char *in)
162 {
163         int i;
164         int index;
165         int len;
166         char *buf = NULL;
167         char c;
168
169         len = strlen(in);
170         buf = (char*) calloc(1, len*2+1);
171         if (buf) {
172                 for (i = 0, index = 0; i < len; i++) {
173                         c = in[i];
174                         if (c == ';')
175                                 buf[index++] = '\\';
176
177                         buf[index++] = c;
178                 }
179
180                 strncpy(in, buf, len*2+1);
181                 free(buf);
182         }
183
184         return(0);
185 }
186
187
188
189 /*
190  * vManySpace2Space() converts multiple spaces to single space in 'in'.
191  *
192  * @param      in                 [inout] pointer to string.
193  * @return     int                length of converted string.
194  */
195 int
196 _VManySpace2Space(char *in)
197 {
198         int             i, j;
199         int             spaced = 0;
200
201         j = 0;
202         for (i = 0; in[i]; i++) {
203                 if (_VIsSpace(in[i])) {
204                         if (!spaced) {
205                                 in[j] = WSP;
206                                 spaced = 1;
207                                 j++;
208                         }
209                 } else {
210                         spaced = 0;
211                         in[j] = in[i];
212                         j++;
213                 }
214         }
215
216
217         in[j] = '\0';
218
219         return j;
220 }
221
222
223 /**
224  * vFindBase64() returns the integer repesentation of the location in base64 table.
225  *
226  * @param      in                a character
227  * @return     int               The base64 table location of input character
228  */
229 int
230 __VFindBase64(char in)
231 {
232         int             i;
233
234         for (i = 0; i < 65; i++) {
235                 if (Base64Table[i] == in)
236                         return i;
237         }
238         return -1;
239 }
240
241
242
243 /**
244  * vBase64Check() returns the total length of input except non-base64 value.
245  *
246  * @param      in               char values which are base64 or non-base64
247  * @return     int              the total length of input except non-base64
248  */
249 int
250 __VBase64Check(char *in)
251 {
252         int             i = 0, j = 0;
253         int             base;
254
255         while (in[i]) {
256                 base = __VFindBase64(in[i]);
257                 if (base < 0) {
258                         i++;
259                 } else {
260                         in[j] = in[i];
261                         j++; i++;
262                 }
263         }
264
265         in[j] = '\0';
266
267         return j;
268 }
269
270 /**
271  * vBase64Decoder() decodes the base64 encoded input.
272  *
273  * @param      Src                Base64 encoded input
274  * @param      Dest               The destination buffer of decoded value
275  * @return     int                The total length decoded value
276  */
277 int
278 _VB64Decode(char *Dest, char *Src)
279 {
280         char*           Encoded = Src;
281         int                     i, j = 0;
282         int                     res;
283         char            Base = 0;
284         char            DecodeTemp;
285         char            Debuffer[4] = {0x00, 0x00, 0x00, '\0'};
286         int                     index = 0;
287         int                     len;
288
289         len = __VBase64Check(Src);
290
291         VDATA_TRACE("total length of Src except non-base64 value = %d", len);
292
293         while (*Encoded) {
294                 for (i = 0; i < 3; i++)
295                         Debuffer[i] = 0x00;
296
297                 for (i = 0; i < 4; i++, Encoded++, j++) {
298                         if (*Encoded == 0x00) break;
299                         if ((res = __VFindBase64(*Encoded)) < 0)        continue;
300
301                         Base = (char)res;
302                         DecodeTemp = 0x00;
303
304                         if (Base == 64) {
305                                 Encoded++;
306                                 break;
307                         }
308
309                         switch (i) {
310                         case 0:
311                                 DecodeTemp = Base << 2;
312                                 Debuffer[0] |= DecodeTemp;
313                                 break;
314                         case 1:
315                                 DecodeTemp = Base >> 4;
316                                 Debuffer[0] |= DecodeTemp;
317                                 DecodeTemp = Base << 4;
318                                 Debuffer[1] |= DecodeTemp;
319                                 break;
320                         case 2:
321                                 DecodeTemp = Base >> 2;
322                                 Debuffer[1] |= DecodeTemp;
323                                 DecodeTemp = Base << 6;
324                                 Debuffer[2] |= DecodeTemp;
325                                 break;
326                         case 3:
327                                 DecodeTemp = Base;
328                                 Debuffer[2] |= DecodeTemp;
329                                 break;
330                         }
331                 }
332
333                 if (Base == 64) {
334                         switch (i) {
335                         case 0: break;
336                         case 1:
337                         case 2:
338                                 Dest[index] = Debuffer[0];
339                                 index++;
340                                 break;
341                         case 3:
342                                 Dest[index++] = Debuffer[0];
343                                 Dest[index++] = Debuffer[1];
344                                 break;
345                         }
346                 } else {
347                         Dest[index++] = Debuffer[0];
348                         Dest[index++] = Debuffer[1];
349                         Dest[index++] = Debuffer[2];
350                 }
351         }
352
353         return index;
354 }
355
356
357 /**
358  * vBase64Encoder() encode the input to base64.
359  *
360  * @param      Src                non-base64 char input
361  * @param      Dest               The destination buffer of encoded value
362  * @return     0
363  */
364 int
365 _VB64Encode(char *Dest, char *Src, int len)
366 {
367         char*   Encoded = Dest;
368         char*   Decoded = Src;
369         int             i, j;
370         int             index;
371         int             res = 0;
372         int             base1 = 0, base2 = 0;
373         char    Enbuffer[4] = {0,};
374         char    Debuffer[3] = {0,};
375         int             length = 0;
376
377         for (i = 0; i < 4; i++)
378                 Enbuffer[i] = 0x00;
379
380         for (i = 0; i < len; i++) {
381                 res = i%3;
382
383                 switch (res) {
384                 case 0:
385                         Debuffer[0] = *Decoded;
386                         break;
387                 case 1:
388                         Debuffer[1] = *Decoded;
389                         break;
390                 case 2:
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];
404
405                         Encoded[length++] = Enbuffer[0];
406                         Encoded[length++] = Enbuffer[1];
407                         Encoded[length++] = Enbuffer[2];
408                         Encoded[length++] = Enbuffer[3];
409
410                         for (j = 0; j < 3; j++)
411                                 Debuffer[j] = 0x00;
412
413                         break;
414                 }
415
416                 Decoded++;
417         }
418
419         res = i % 3;
420
421         switch (res) {
422         case 0:
423                 break;
424         case 1:
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];
433
434                 Encoded[length++] = Enbuffer[0];
435                 Encoded[length++] = Enbuffer[1];
436                 Encoded[length++] = Enbuffer[2];
437                 Encoded[length++] = Enbuffer[3];
438
439                 break;
440         case 2:
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];
452
453                 Encoded[length++] = Enbuffer[0];
454                 Encoded[length++] = Enbuffer[1];
455                 Encoded[length++] = Enbuffer[2];
456                 Encoded[length++] = Enbuffer[3];
457
458                 break;
459         }
460
461         Encoded[length] = '\0';
462
463         return 0;
464 }
465
466
467
468 int
469 __VRepChar2Space(char *vRaw, char replaced)
470 {
471         int length = 0;
472
473         while (*vRaw) {
474                 if (*vRaw == replaced)
475                         *vRaw = WSP;
476
477                 vRaw++;
478                 length++;
479         }
480
481         return length;
482 }
483
484
485 /**
486  * vUnfolding() unfold the folded line.
487  *
488  * @param      string             The folded line input
489  * @return     int                Total length of unfolded output
490  */
491 int
492 _VUnfolding(char *string)
493 {
494         unsigned int i, j;
495         unsigned int len;
496
497         len = strlen(string);
498
499         for (i = 0, j = 0; i < len; i++, j++) {
500                 string[j] = string[i];
501
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)) {
505                                 if (j < 2)
506                                         j = 0;
507                                 else
508                                         j -= 2;
509
510                                 string[i-1] = 0;
511                         }
512
513                         if (i >= 2 && (string[i-2] == LF || string[i-2] == CR)) {
514                                 if (j < 1)
515                                         j = 0;
516                                 else
517                                         j -= 1;
518
519                                 string[i-2] = 0;
520                         }
521                 }
522         }
523
524         string[j] = '\0';
525
526         return j;
527 }
528
529
530 int
531 __VIsNewType(char *pCardRaw)
532 {
533         int count = 0, i = 0, low = 0, high = 0, diff = 0;
534         char strTypeName[50] = {0};
535
536         while (1) {
537                 if (*pCardRaw == CR || *pCardRaw == LF)
538                         pCardRaw++;
539                 else {
540                         if (*pCardRaw == ';' || *pCardRaw == ':' || count >= 50)
541                                 break;
542                         else
543                                 strTypeName[count++] = *pCardRaw++;
544                 }
545
546         }
547
548
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 */
553                         return true;
554         }
555
556
557
558         return false;
559         /* res = __VCardGetName(strTypeName, (char**)pszCardTypeList, VCARD_TYPE_NUM); */
560 }
561
562
563 int
564 __VIsNewTypeforOrg(char *pCardRaw, int vType)
565 {
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[];
570
571         while (1) {
572                 if (*pCardRaw == CR || *pCardRaw == LF)
573                         pCardRaw++;
574                 else {
575                         if (*pCardRaw == ';' || *pCardRaw == ':' || count >= 50)
576                                 break;
577                         else
578                                 strTypeName[count++] = *pCardRaw++;
579                 }
580         }
581
582         if (vType == VCARD)
583                 vTypeNum = VCARD_TYPE_NUM;
584         else if (vType == VMESSAGE)
585                 vTypeNum = VMSG_TYPE_NUM;
586         else
587                  return false;
588
589         for (low = 0, high = vTypeNum - 1; high >= low; diff < 0 ? (low = i+1) : (high = i-1)) {
590                 i = (low + high) / 2;
591
592                 if (vType == VCARD)
593                         diff = strcmp(pszCardTypeList[i], strTypeName);
594                 else if (vType == VMESSAGE)
595                         diff = strcmp(pszMsgTypeList[i], strTypeName);
596
597                 if (diff == 0)  /* success: found it */
598                         return true;
599                 else if (!strncmp(strTypeName, "X-", 2))
600                         return true;
601         }
602
603         /* if (count <= 50) return TRUE; */
604
605         return false;
606
607         /* res = __VCardGetName(strTypeName, (char**)pszCardTypeList, VCARD_TYPE_NUM); */
608 }
609
610 char*
611 _VUnfoldingNoSpecNew(char *string)
612 {
613         unsigned int i, j;
614         unsigned int len;
615
616         char* newString;
617
618         len = strlen(string);
619
620         if (!(newString = (char*) calloc(1, len+1)))
621                 return NULL;
622
623         for (i = 0, j = 0; i < len; i++, j++) {
624
625                 newString[j] = string[i];
626
627                 if (i < len-5) {
628
629                         if (string[i] == '=') {
630
631                                 if (string[i+1] == CR && string[i+2] == LF) {
632
633                                         if (__VIsNewType(string) == false) {
634                                                 if (j >= 2)
635                                                         j -= 2;
636                                                 else
637                                                         j = 0;
638                                                 i += 2;
639                                         }
640                                 } else if (string[i+1] == CR || string[i+1] == LF) {
641                                         if (__VIsNewType(string) == false) {
642                                                 if (j >= 1)
643                                                         j -= 1;
644                                                 else
645                                                         j = 0;
646                                                 i += 1;
647                                         }
648                                 }
649                         } else if (string[i] == ' ') {
650
651                                 if (i >= 2 && string[i-2] == CR && string[i-1] == LF) {
652                                         if (__VIsNewType(string) == false) {
653                                                 if (j >= 3)
654                                                         j -= 3;
655                                                 else
656                                                         j = 0;
657                                         } else {
658                                                 j -= 1;
659                                         }
660                                 } else if (i >= 1 && (string[i-1] == CR || string[i-1] == LF)) {
661                                         if (j >= 2)
662                                                 j -= 2;
663                                         else
664                                                 j = 0;
665                                 }
666                         } else if ((string[i] == CR || string[i] == LF) && __VIsNewType(string) == false) {
667
668                                 if (string[i+1] == LF) {
669                                         if (j >= 1)
670                                                 j -= 1;
671                                         else
672                                                 j = 0;
673                                         i += 1;
674                                 }
675                         }
676                 }
677         }
678
679         newString[j] = '\0';
680
681         return newString;
682 }
683
684 /**
685  * vUnfolding() unfold the folded line.
686  *
687  * @param      string             The folded line input
688  * @return     int                Total length of unfolded output
689  */
690 int
691 _VUnfoldingNoSpec(char *string, int vType)
692 {
693         unsigned int i, j;
694         unsigned int len;
695
696         len = strlen(string);
697
698         for (i = 0, j = 0; i < len; i++, j++) {
699                 string[j] = string[i];
700
701                 if ((i < len-5)) {
702                         if (string[i] == '=') {
703                                 if (string[i+1] == CR && string[i+2] == LF && string[i+3] == '=') {
704                                         string[i] = 0;
705                                         string[i+1] = 0;
706                                         string[i+2] = 0;
707                                         if (j > 0)
708                                                  j -= 1;
709                                         i += 2;
710                                 } else if (string[i+1] == CR && string[i+2] == LF &&  __VIsNewTypeforOrg(&string[i+3], vType) == false) {
711                                         string[i] = 0;
712                                         string[i+1] = 0;
713                                         string[i+2] = 0;
714                                         if (j > 0)
715                                                 j -= 1;
716                                         i += 2;
717                                 }
718                         } else if (string[i] == WSP || string[i] == TAB) {
719                                 if (i >= 2 && string[i-2] == CR && string[i-1] == LF) {
720                                         string[i] = 0;
721                                         string[i-1] = 0;
722                                         string[i-2] = 0;
723                                         if (j >= 3)
724                                                 j -= 3;
725                                         else
726                                                 j = 0;
727                                 } else if (i >= 1 && (string[i-1] == CR || string[i-1] == LF)) {
728                                         string[i] = 0;
729                                         string[i-1] = 0;
730
731                                         if (j >= 2)
732                                                 j -= 2;
733                                         else
734                                                 j = 0;
735                                 }
736                         }
737
738                 }
739         }
740
741         string[j] = '\0';
742
743         return j;
744 }
745
746 /**
747  * vFolding() decodes the base64 encoded input.
748  *
749  * @param      contentline        Original line (unfolded)
750  * @param      Dest               The destination buffer of folded result
751  */
752 void
753 _VFolding(char *result, char *contentline)
754 {
755         int             i = 0;
756
757         while (*contentline) {
758                 if (i == 75) {
759                         i = 0;
760                         *result++ = '\r';
761                         *result++ = '\n';
762                         *result++ = ' ';
763                 }
764
765                 *result++ = *contentline++;
766                 i++;
767         }
768
769         *result++ = '\0';
770 }
771
772
773 /**
774  * vFolding() decodes the base64 encoded input.
775  *
776  * @param      contentline        Original line (unfolded)
777  * @param      Dest               The destination buffer of folded result
778  */
779 void
780 _VFoldingQP(char *result, char *contentline)
781 {
782         int             i = 0;
783
784         while (*contentline) {
785                 if (i == 74) {
786                         i = 0;
787                         *result++ = '=';
788                         *result++ = '\r';
789                         *result++ = '\n';
790                 }
791
792                 *result++ = *contentline++;
793                 i++;
794         }
795
796         *result++ = '\0';
797 }
798
799
800 /**
801  * vFolding() decodes the base64 encoded input.
802  *
803  * @param      contentline        Original line (unfolded)
804  * @param      Dest               The destination buffer of folded result
805  */
806 void
807 _VFoldingNoSpace(char *result, char *contentline)
808 {
809         int             i = 0;
810
811         while (*contentline) {
812                 if (i == 75) {
813                         i = 0;
814                         *result++ = '\r';
815                         *result++ = '\n';
816                 }
817
818                 *result++ = *contentline++;
819                 i++;
820         }
821
822         *result++ = '\0';
823 }
824
825
826 /**
827  * vQuotedPrintalbeDecoder() decodes the quoted-printable encoded input.
828  *
829  * @param      Src                Quoted-printable encoded input
830  * @return     int                The total length decoded value
831  */
832 int
833 _VQPDecode(char *src)
834 {
835         int             i = 0, j = 0;
836         char    qp[2];
837         char    decodedNum;
838
839         while (src[i]) {
840                 if (src[i] == '=') {
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')) {
844                                         src[j] = '\n';
845                                         j++;
846                                         i += 6;
847                                 } else {
848                                         qp[0] = src[i + 1];
849                                         qp[1] = src[i + 2];
850                                         decodedNum = __VHexaDecoder(qp);
851                                         src[j] = decodedNum;
852                                         i += 3; j++;
853                                 }
854                         } else {
855                                 i += 3;
856                         }
857                 } else {
858                         src[j] = src[i];
859                         i++; j++;
860                 }
861         }
862
863         src[j] = '\0';
864
865         j =     _VManySpace2Space(src);
866
867         return j;
868 }
869
870
871
872 /**
873  * vQuotedPrintableEncoder() decodes the quoted-printalbe encoded input.
874  *
875  * @param      Src                Quoted-printable encoded input
876  * @param      Dest               The destination buffer of decoded value
877  * @return     int                The total length decoded value
878  */
879 int
880 _VQPEncode(char *dest, char *src)
881 {
882         int             i = 0, j = 0, k = 0;
883         char    encoded[2] = {0x0f, 0x0f};
884
885         while (src[i] /*&& (src[i] > 0)*/) {
886                 if (k == 73 && _VIsSpace(src[i])) {
887                         if (src[i] == WSP) {
888                                 dest[j++] = '='; dest[j++] = '2'; dest[j++] = '0';
889                                 k += 3;
890                         } else if (src[i] == TAB) {
891                                 dest[j++] = '='; dest[j++] = '0'; dest[j++] = '9';
892                                 k += 3;
893                         }
894                 /*} else if (k == 76) {
895                         dest[j++] = '='; dest[j++] = WSP;
896                         k = 0;
897                         */
898                 } else if (!__VIsPrintable(src[i])) {
899                         dest[j++] = '=';
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;
905                         k += 3;
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;
909                 } else {
910                         dest[j++] = src[i]; k++;
911                 }
912                 i++;
913         }
914
915         dest[j] = '\0';
916
917         return j;
918 }
919
920
921 /**
922  * vIsPrintable() check whether the input is printable.
923  *
924  * @param      in
925  * @return     true/false            if input is printable :true else : false
926  */
927 int
928 __VIsPrintable(char in)
929 {
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;
934         else return false;
935 }
936
937
938
939 /**
940  * vHexaDecoder() output the character value of inputed hexadecimal value.
941  *
942  * @param      qp               Hexadecimal input value
943  * @return     char             Character representation of input hexadecimal value
944  */
945 char
946 __VHexaDecoder(char *qp)
947 {
948         int             i;
949         char    decoded[2] = {0x00, 0x00};
950         char    res;
951
952         for (i = 0; i < 2; i++) {
953                 switch (qp[i]) {
954                 case '0':
955                         decoded[i] = 0x00;
956                         break;
957                 case '1':
958                         decoded[i] = 0x01;
959                         break;
960                 case '2':
961                         decoded[i] = 0x02;
962                         break;
963                 case '3':
964                         decoded[i] = 0x03;
965                         break;
966                 case '4':
967                         decoded[i] = 0x04;
968                         break;
969                 case '5':
970                         decoded[i] = 0x05;
971                         break;
972                 case '6':
973                         decoded[i] = 0x06;
974                         break;
975                 case '7':
976                         decoded[i] = 0x07;
977                         break;
978                 case '8':
979                         decoded[i] = 0x08;
980                         break;
981                 case '9':
982                         decoded[i] = 0x09;
983                         break;
984                 case 'a':
985                 case 'A':
986                         decoded[i] = 0x0a;
987                         break;
988                 case 'b':
989                 case 'B':
990                         decoded[i] = 0x0b;
991                         break;
992                 case 'c':
993                 case 'C':
994                         decoded[i] = 0x0c;
995                         break;
996                 case 'd':
997                 case 'D':
998                         decoded[i] = 0x0d;
999                         break;
1000                 case 'e':
1001                 case 'E':
1002                         decoded[i] = 0x0e;
1003                         break;
1004                 case 'f':
1005                 case 'F':
1006                         decoded[i] = 0x0f;
1007                         break;
1008                 }
1009         }
1010
1011         res = (char)((decoded[0] << 4) + decoded[1]);
1012
1013         return res;
1014 }
1015
1016
1017
1018 /**
1019  * vHexaEncoder() output the hexadecimal value of input character value.
1020  *
1021  * @return     qp               Character representation of input hexadecimal value
1022  */
1023 void
1024 __VHexaEncoder(char *qp)
1025 {
1026         int             i;
1027
1028         for (i = 0; i < 2; i++) {
1029                 switch (qp[i]) {
1030                 case 0:
1031                         qp[i] = '0';
1032                         break;
1033                 case 1:
1034                         qp[i] = '1';
1035                         break;
1036                 case 2:
1037                         qp[i] = '2';
1038                         break;
1039                 case 3:
1040                         qp[i] = '3';
1041                         break;
1042                 case 4:
1043                         qp[i] = '4';
1044                         break;
1045                 case 5:
1046                         qp[i] = '5';
1047                         break;
1048                 case 6:
1049                         qp[i] = '6';
1050                         break;
1051                 case 7:
1052                         qp[i] = '7';
1053                         break;
1054                 case 8:
1055                         qp[i] = '8';
1056                         break;
1057                 case 9:
1058                         qp[i] = '9';
1059                         break;
1060                 case 10:
1061                         qp[i] = 'A';
1062                         break;
1063                 case 11:
1064                         qp[i] = 'B';
1065                         break;
1066                 case 12:
1067                         qp[i] = 'C';
1068                         break;
1069                 case 13:
1070                         qp[i] = 'D';
1071                         break;
1072                 case 14:
1073                         qp[i] = 'E';
1074                         break;
1075                 case 15:
1076                         qp[i] = 'F';
1077                         break;
1078                 }
1079         }
1080
1081 }
1082
1083 /**
1084  * _VIsCrLf() returns one if char is either a space, tab, or newline.
1085  *
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.
1090  */
1091 int
1092 _VIsCrLf(char in)
1093 {
1094         if ((in == CR) || (in == LF))
1095                 return 1;
1096         else
1097                 return 0;
1098 }
1099
1100 /*
1101  * vManySpace2Space() converts multiple spaces to single space in 'in'.
1102  *
1103  * @param      in                 [inout] pointer to string.
1104  * @return     int                length of converted string.
1105  */
1106 int
1107 _VManyCRLF2CRLF(char *pIn)
1108 {
1109         int             i, j;
1110         bool    bCrLf = false, bFirstCrLf = true;
1111
1112         j = 0;
1113         for (i = 0; pIn[i]; i++) {
1114                 if (_VIsCrLf(pIn[i]) && _VIsCrLf(pIn[i+1])) {
1115                         if (bFirstCrLf && !bCrLf) {
1116                                 bCrLf = 1;
1117                         } else if (!bFirstCrLf) {
1118                                 if (!bCrLf) {
1119                                         pIn[j] = CR;
1120                                         pIn[++j] = LF;
1121                                         bCrLf = true;
1122                                         j++;
1123                                 }
1124                         }
1125                         i++;
1126                 } else {
1127                         bCrLf = false;
1128                         bFirstCrLf = false;
1129                         pIn[j] = pIn[i];
1130                         j++;
1131                 }
1132         }
1133
1134         pIn[j] = '\0';
1135
1136         return j;
1137 }