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