merge with master
[platform/core/system/sync-agent.git] / src / fw-plugins / common-public / vcalendar-task / src / encoding_util.c
1 /*
2  * sync-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <glib.h>
19 #include <glib/gprintf.h>
20
21 #include "encoding_util.h"
22
23 /* for log */
24 #include "utility/sync_util.h"
25
26 #ifndef SYNC_AGENT_LOG
27 #undef LOG_TAG
28 #define LOG_TAG "ENCODING_UTIL"
29 #endif
30
31 #define TYPE_CHECK_BUF_SIZE                     100     /* temporary definition */
32 #define TEMP_BUFFER_SIZE                                1024    /* temporary definition */
33
34 /* BASE64 TABLE */
35 static char base64_table[65] = {
36         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
37         'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
38         'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',
39         'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
40         'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
41         't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',
42         '2', '3', '4', '5', '6', '7', '8', '9', '+',
43         '/', '='
44 };
45
46 /* Quoted-Printable */
47 static char *_dec_to_hex(int dec);
48 static int _hex_to_dec(char *hex);
49
50 /* Base64 */
51 static int _find_base(char ch);
52
53 /*
54  *      Quoted-Printable
55  */
56 int encode_qp(char *src, int src_len, char **en_src, int *en_src_len)
57 {
58         _EXTERN_FUNC_ENTER;
59
60         retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
61
62         char *en_hex;
63         int i = 0;
64         int j = 0;
65         int size_cnt = 0;
66
67         if (src == NULL) {
68                 _DEBUG_ERROR("[encoding_util] src is NULL\n");
69                 return 0;
70         }
71
72         /*encoded string length is three times longer than existing maximum string length */
73         int full_lenth = src_len * 3 + 1 + (int)(src_len * 3 / 76) * 3;
74         *en_src = (char *)malloc(sizeof(char) * full_lenth);
75         if (*en_src == NULL) {
76                 _DEBUG_ERROR("[encoding_util] malloc fail !!\n");
77                 return 0;
78         }
79         memset(*en_src, 0x00, src_len * 3 + 1);
80
81         _DEBUG_INFO("[encoding_util] src_len : %d\n", src_len);
82         for (i = 0; i < src_len; i++) {
83                 /* _DEBUG_INFO("[encoding_util] i : %d\n", i); */
84                 if (size_cnt >= QP_SIZE - 3) {
85                         size_cnt = 0;
86                         (*en_src)[j++] = 0x3D;
87                         (*en_src)[j++] = 0x0D;
88                         (*en_src)[j++] = 0x0A;
89                 }
90
91                 if ((src[i] >= 33 && src[i] <= 126) || (src[i] == 0x0A) || (src[i] == 0x0D)) {
92                         if (src[i] == 61 || src[i] == 0x0A || src[i] == 0x0D) {
93                                 en_hex = _dec_to_hex(src[i]);
94                                 (*en_src)[j++] = 0x3D;  /* '=' */
95                                 (*en_src)[j++] = en_hex[0];
96                                 (*en_src)[j++] = en_hex[1];
97                                 size_cnt += 3;
98                         } else {
99                                 size_cnt++;
100                                 (*en_src)[j++] = src[i];
101                         }
102                 } else if (src[i] == 9 || src[i] == 32) {
103                         if (src[i + 1] == 0x0A || src[i + 1] == '\0') { /* TAB or WhiteSpace */
104                                 en_hex = _dec_to_hex(src[i]);
105                                 (*en_src)[j++] = 0x3D;  /* '=' */
106                                 (*en_src)[j++] = en_hex[0];
107                                 (*en_src)[j++] = en_hex[1];
108                                 size_cnt += 3;
109                         } else {
110                                 size_cnt++;
111                                 (*en_src)[j++] = src[i];
112                         }
113                 } else {
114                         en_hex = _dec_to_hex(src[i]);
115                         (*en_src)[j++] = 0x3D;  /* '=' */
116                         (*en_src)[j++] = en_hex[0];
117                         (*en_src)[j++] = en_hex[1];
118                         _DEBUG_INFO("[encoding_util] en_src : %s\n", *en_src);
119                         size_cnt += 3;
120                 }
121         }
122
123         (*en_src)[j] = 0x00;
124         *en_src_len = size_cnt;
125
126         _EXTERN_FUNC_EXIT;
127
128         return 1;
129 }
130
131 int decode_qp(char *src, int src_len, char **de_src, int *de_src_len)
132 {
133         _EXTERN_FUNC_ENTER;
134
135         retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
136
137         char hex[3];
138         char ch;
139         int dec = 0;
140         int i = 0;
141         int j = 0;
142         int is_space = 0;
143         int is_equal = 0;
144
145         if (src == NULL) {
146                 _DEBUG_ERROR("[encoding_util] src is NULL\n");
147                 return 0;
148         }
149
150         *de_src = (char *)malloc(sizeof(char) * (src_len + 1));
151         if (*de_src == NULL) {
152                 _DEBUG_ERROR("[encoding_util] malloc is fail !!\n");
153                 return 0;
154         }
155         memset(*de_src, 0x00, sizeof(char) * (src_len + 1));
156
157         while (src[i] != '\0') {
158                 if (src[i] == 0x3D) {   /* '=' */
159                         /* check whiteSpace */
160                         ch = src[++i];
161
162                         /* '=' skip if next character is a TAB or WhiteSpace */
163                         while (ch == 0x09 || ch == 0x20) {
164                                 is_space = 1;
165                                 ch = src[++i];
166                                 break;
167                         }
168
169                         if (is_space == 1) {
170                                 is_space = 0;
171                                 continue;
172                         }
173
174                         /* '=' skip if next character is 3D which means '=' (encoding error case ??) */
175                         while (ch == '3') {
176                                 ch = src[++i];
177
178                                 if (ch == 'D') {
179                                         is_equal = 1;
180                                         ch = src[++i];
181                                         break;
182                                 }
183                         }
184
185                         if (is_equal == 1) {
186                                 is_equal = 0;
187                                 goto insert_equal;
188                         }
189
190                         /* if next character is LF after '=' do doft line break
191                          * encoded QP string on one line 76 character is allowed
192                          */
193                         if (ch == 0x0D) {       /* LF */
194                                 ch = src[++i];
195                                 if (ch == 0x0A) {
196                                         ch = src[++i];
197                                         continue;
198                                 }
199                         }
200
201                         hex[0] = src[i++];
202                         hex[1] = src[i++];
203                         hex[2] = '\0';
204
205                         dec = _hex_to_dec(hex);
206
207                         /* decoding error */
208                         if (dec < 0) {
209                                 /* when error occur, restore the previous encoding message */
210                                 (*de_src)[j++] = 0x3D;  /* '=' */
211                                 (*de_src)[j++] = hex[0];
212                                 (*de_src)[j++] = hex[1];
213                         } else {
214                                 (*de_src)[j++] = dec;
215                         }
216                         continue;
217                 } else if (src[i] > 0x7E) {     /* encoding error */
218                         i++;    /* ignore that character */
219                         continue;
220                 } else {
221                         (*de_src)[j++] = src[i++];
222                         continue;
223                 }
224
225  insert_equal:
226                 (*de_src)[j++] = 0x3D;
227         }
228
229         (*de_src)[j] = '\0';
230         *de_src_len = j;
231
232         _EXTERN_FUNC_EXIT;
233
234         return 1;
235 }
236
237 static char *_dec_to_hex(int dec)
238 {
239         _INNER_FUNC_ENTER;
240
241         static char hex[3];
242         int i;
243         int ch;
244
245         for (i = 0; i < 2; i++) {
246                 if (i == 0) {
247                         ch = (dec & 0xF0) >> 4;
248                 } else if (i == 1) {
249                         ch = (dec & 0x0F);
250                 }
251
252                 if (ch >= 10) {
253                         hex[i] = 'A' + ch - 10;
254                 } else {
255                         hex[i] = '0' + ch;
256                 }
257         }
258
259         hex[i] = 0x00;
260
261         _DEBUG_TRACE("[encoding_util] hex : %s\n", hex);
262
263         _INNER_FUNC_EXIT;
264
265         return &hex[0];
266 }
267
268 static int _hex_to_dec(char *hex)
269 {
270         _INNER_FUNC_ENTER;
271
272         int dec = 0;
273         int byte;
274         int i = 0;
275
276         for (i = 0; i < 2; i++) {
277                 if (hex[i] >= '0' && hex[i] <= '9') {
278                         byte = hex[i] - '0';
279                 } else if (hex[i] >= 'A' && hex[i] <= 'F') {
280                         byte = hex[i] - 'A' + 10;
281                 } else if (hex[i] >= 'a' && hex[i] <= 'f') {
282                         byte = hex[i] - 'a' + 10;
283                 } else {
284                         byte = -1;
285                 }
286
287                 if (byte < 0)
288                         return -1;
289
290                 dec += (i == 0) ? byte << 4 : byte;
291         }
292
293         _INNER_FUNC_EXIT;
294
295         return dec;
296 }
297
298 /*
299  *      Base64
300  */
301 int encode_base64(char *src, int src_len, char **en_src, int *en_src_len)
302 {
303         _EXTERN_FUNC_ENTER;
304
305         retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
306
307         int i = 0;
308         int j = 0;
309         int cnt = 0;
310         int ch = 0;
311         int size_cnt = 0;
312
313         if (src == NULL) {
314                 _DEBUG_ERROR("[encoding_util] src is NULL\n");
315                 return 0;
316         }
317
318         *en_src = (char *)malloc(sizeof(char) * (src_len * 2));
319
320         if (*en_src == NULL) {
321                 _DEBUG_ERROR("[encoding_util] malloc fail !!\n");
322                 return 0;
323         }
324         memset(*en_src, 0x00, src_len * 2);
325
326         while (1) {
327                 switch (cnt++) {
328                 case 0:
329                         {
330                                 if (i < src_len) {
331                                         ch = (src[i] & 0xFC) >> 2;
332                                 } else {
333                                         ch = -1;
334                                 }
335                         }
336                         break;
337
338                 case 1:
339                         {
340                                 if (i < src_len) {
341                                         if (i + 1 < src_len) {
342                                                 ch = ((src[i] & 0x03) << 4) | ((src[i + 1] & 0xF0) >> 4);
343                                         } else {
344                                                 ch = ((src[i] & 0x03) << 4);
345                                         }
346                                 } else {
347                                         ch = -1;
348                                 }
349                                 i++;
350                                 break;
351                         }
352
353                 case 2:
354                         {
355                                 if (i < src_len) {
356                                         if (i + 1 < src_len) {
357                                                 ch = ((src[i] & 0x0F) << 2) | ((src[i] & 0xC0) >> 6);
358                                         } else {
359                                                 ch = ((src[i] & 0x0F) << 2);
360                                         }
361                                 } else {
362                                         ch = -1;
363                                 }
364                                 i++;
365                         }
366                         break;
367
368                 case 3:
369                         {
370                                 if (i < src_len) {
371                                         ch = (src[i] & 0x3F);
372                                 } else {
373                                         ch = -1;
374                                 }
375                                 i++;
376                                 cnt = 0;
377                         }
378                         break;
379                 }
380
381                 /*
382                    if (ch >= 0 && ch <= 25) {           // Upper Case Alphabet
383                    (*en_src)[j++] = 'A' + ch;
384                    } else if (ch >= 26 && ch <= 51) {           // Lower Case Alphabet
385                    (*en_src)[j++] = 'a' + ch - 26;
386                    } else if (ch >= 52 && ch <= 61) {           // Digit
387                    (*en_src)[j++] = '0' + ch - 52;
388                    } else if (ch == 62) {
389                    (*en_src)[j++] = '+';
390                    } else if (ch == 63) {
391                    (*en_src)[j++] = '/';
392                    } else if (ch == -1) {
393                    (*en_src)[j++] = '=';                // padding
394                    }
395                  */
396
397                 if ((ch != -1) && (ch >= 0 && ch <= 64)) {
398                         (*en_src)[j++] = base64_table[ch];
399                 } else {
400                         (*en_src)[j++] = base64_table[64];      /* padding */
401                 }
402
403                 size_cnt++;
404
405                 if (j % 4 == 0) {
406                         if (size_cnt == BASE64_SIZE) {
407                                 size_cnt = 0;
408                                 (*en_src)[j++] = 0x0A;  /* soft line break */
409                         }
410
411                         if (i >= src_len)
412                                 break;
413                 }
414         }
415
416         (*en_src)[j] = 0x00;
417         *en_src_len = j;
418
419         _EXTERN_FUNC_EXIT;
420
421         return 1;
422 }
423
424 int decode_base64(char *src, int src_len, char **de_src, int *de_src_len)
425 {
426         _EXTERN_FUNC_ENTER;
427
428         retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
429
430         long tmp = 0;           /* 4byte (using decoding) */
431         int i = 0;
432         int j = 0;
433         int cnt = 0;
434         int pad_cnt = 0;
435
436         if (src == NULL) {
437                 _DEBUG_ERROR("[encoding_util] src is NULL\n");
438                 return 0;
439         }
440
441         /* de_src is enough for the src_len 3/4 size */
442         *de_src = (char *)malloc(sizeof(char) * (src_len));
443         if (*de_src == NULL) {
444                 _DEBUG_ERROR("malloc error !!");
445                 return 0;
446         }
447         memset(*de_src, 0x00, src_len);
448
449         if (*de_src == NULL) {
450                 _DEBUG_ERROR("[encoding_util] malloc is fail !!\n");
451                 return 0;
452         }
453
454         while (src[i] != '\0') {
455                 /*
456                    if (isupper(src[i])) {
457                    tmp = (tmp << 6) | (src[i] - 'A');           // Upper case : 0 ~ 25
458                    } else if (islower(src[i])) {
459                    tmp = (tmp << 6) | (src[i] - 'a' + 0x1A);            // Lower case : 26(0x1A) ~ 51
460                    } else if (isdigit(src[i])) {
461                    tmp = (tmp << 6) | (src[i] - '0' + 0x34);    // Number : 52(0x34) ~ 61
462                    } else if (src[i] == '+') {
463                    tmp = (tmp << 6) | 0x3E;             // '+' : 62(0x3E)
464                    } else if (src[i] == '/') {
465                    tmp = (tmp << 6) | 0x3F;                     // '/' : 63(0x3F)
466                    } else if (src[i] == '=') {
467                    pad_cnt++;
468                    tmp = (tmp << 6);                                    // '=' : padding
469                    } else {
470                    tmp = (tmp << 6);                                    // encoding error
471                    f_DEBUG_INFO(stdout, "encoding error !! \n");
472                    }
473                  */
474
475                 tmp = (tmp << 6) | (_find_base(src[i]));
476                 if (tmp == 64) {
477                         pad_cnt++;
478                 } else if (tmp == -1) {
479                         _DEBUG_ERROR("[encoding_util] encoding error \n");
480                 }
481
482                 if (++cnt >= 4) {
483                         (*de_src)[j++] = (char)((tmp & 0x00FF0000) >> 16);
484                         (*de_src)[j++] = (char)((tmp & 0x0000FF00) >> 8);
485                         (*de_src)[j++] = (char)(tmp & 0x000000FF);
486
487                         cnt = 0;
488                         tmp = 0;
489
490                         if (src[i + 1] == 0x0A) {       /* soft line break */
491                                 i++;
492                         }
493                 }
494
495                 i++;
496         }
497
498         (*de_src)[j - pad_cnt] = '\0';
499         *de_src_len = j - pad_cnt;
500
501         _EXTERN_FUNC_EXIT;
502
503         return 1;
504 }
505
506 int proc_decoding(const char *src, int src_len, char **de_src, int *de_src_len)
507 {
508         _EXTERN_FUNC_ENTER;
509
510         retvm_if(src == NULL, 0, "[encoding_util] src is NULL\n");
511
512         const char *reg_src = NULL;
513         reg_src = src;
514
515         _DEBUG_INFO("[encoding_util] << src >> \n%s\n", src);
516
517         *de_src = (char *)malloc(sizeof(char) * (src_len + 1));
518         if (*de_src == NULL) {
519                 _DEBUG_INFO("[encoding_util] malloc error !! \n");
520
521                 return 0;
522         }
523         memset(*de_src, 0x00, sizeof(char) * (src_len + 1));
524
525         char colon[] = ":";
526         char line_breaker[] = "\r\n";
527         char *start_decoding = NULL;
528         int data_size = 0;
529         int res = 0;
530         int de_temp_len = 0;
531         int len = 0;
532
533         char *de_temp = (char *)malloc(sizeof(char) * TEMP_BUFFER_SIZE);        /* todo : temporary */
534         if (de_temp == NULL) {
535                 _DEBUG_ERROR("[encoding_util] malloc error !!\n");
536
537                 if (*de_src != NULL)
538                         free(*de_src);
539
540                 return 0;
541         }
542
543         while ((start_decoding = strstr(src, "ENCODING="))) {
544                 char *charset_loc = strstr(src, "CHARSET=");
545                 char *colon_loc = strstr(start_decoding, colon);        /* find ':''s location */
546                 char *line_breaker_loc = 0;
547
548                 /*edited code for line beaker */
549                 char *colon_loc_temp = colon_loc;
550                 while (line_breaker_loc == NULL) {
551                         line_breaker_loc = strstr(colon_loc_temp, line_breaker);        /* find "\r\n"'s location */
552                         if (line_breaker_loc > colon_loc_temp && !strncmp(line_breaker_loc - 1, "=", 1)) {
553                                 colon_loc_temp = line_breaker_loc + 1;
554                                 line_breaker_loc = 0;
555                         }
556                 }
557
558                 /*
559                  *      if find "ENCODING=" do strcat data until ":" to de_src
560                  */
561                 if (charset_loc != NULL) {
562                         if (start_decoding > charset_loc) {     /* CHARSET=UTF-8;ENCODING=abcxx: */
563                                 data_size = (charset_loc - 1) - src;
564                         } else {        /* ENCODING=abcxxx;CHARSET=UTF-8:       */
565                                 data_size = (start_decoding - 1) - src;
566                         }
567                 } else {
568                         data_size = (start_decoding - 1) - src;
569                 }
570
571                 char *temp = (char *)malloc(sizeof(char) * (data_size + 1));
572                 if (temp == NULL) {
573                         _DEBUG_ERROR("[encoding_util] malloc error !!");
574
575                         if (*de_src != NULL)
576                                 free(*de_src);
577
578                         if (de_temp != NULL)
579                                 free(de_temp);
580
581                         return 0;
582                 }
583                 memset(temp, 0x00, sizeof(char) * (data_size + 1));
584                 memcpy(temp, src, data_size);
585
586                 len = g_strlcat(*de_src, temp, (src_len + 1));
587                 if (len >= (src_len + 1)) {
588                         _DEBUG_ERROR("*de_src buffer overflow !!");
589
590                         if (*de_src != NULL)
591                                 free(*de_src);
592
593                         if (de_temp != NULL)
594                                 free(de_temp);
595
596                         if (temp != NULL)
597                                 free(temp);
598
599                         return 0;
600                 }
601
602                 (*de_src)[strlen(*de_src)] = ':';
603                 if (temp != NULL)
604                         free(temp);
605
606                 _DEBUG_INFO("[encoding_util] << *de_src >> \n %s\n", *de_src);
607
608                 /*
609                  *              copy data from ":" until "\r\n"(actual encoding stream)
610                  */
611                 data_size = line_breaker_loc - colon_loc;       /* from ':' until "\r\n" + '\0' */
612                 char *value = (char *)malloc(sizeof(char) * (data_size + 1));
613                 if (value == NULL) {
614                         _DEBUG_ERROR("[encoding_util] malloc error !!\n");
615
616                         if (*de_src != NULL)
617                                 free(*de_src);
618
619                         if (de_temp != NULL)
620                                 free(de_temp);
621
622                         return 0;
623                 }
624                 memset(value, 0x00, sizeof(char) * (data_size + 1));
625                 memcpy(value, ++colon_loc, data_size);  /* from ':' until "\r\n" */
626                 value[data_size] = '\0';
627                 _DEBUG_INFO("[encoding_util] data len is [%d] and value is [%s]\n\n", data_size, value);
628                 /*
629                  *      Get encoding type using data from "ENCODING=" to ":"
630                  */
631                 char type_check[TYPE_CHECK_BUF_SIZE] = { 0, };
632                 int type_check_size = colon_loc - start_decoding;
633                 strncpy(type_check, start_decoding, type_check_size);
634                 _DEBUG_INFO("[encoding_util] type check : %s\n", type_check);
635                 encoding_type_e type = find_encoding_type((const char *)type_check);
636
637                 /*
638                  *              Process decoding by passing the actual value and encoding type to decode_value()
639                  */
640                 de_temp_len = 0;
641                 memset(de_temp, 0x00, sizeof(char) * TEMP_BUFFER_SIZE); /* todo : temporary */
642
643                 res = decode_value(type, value, data_size, &de_temp, &de_temp_len);
644
645                 if (res != 1) {
646                         _DEBUG_ERROR("[encoding_util] decode_value error !!\n");
647
648                         if (*de_src != NULL)
649                                 free(*de_src);
650
651                         if (de_temp != NULL)
652                                 free(de_temp);
653
654                         if (value != NULL)
655                                 free(value);
656
657                         return 0;
658                 }
659
660                 /*
661                  *      Append decoded data to de_src
662                  */
663                 _DEBUG_INFO("[encoding_util] de_temp : %s\n", de_temp);
664                 len = 0;
665                 len = g_strlcat(*de_src, de_temp, (src_len + 1));
666                 if (len >= (src_len + 1)) {
667                         _DEBUG_ERROR("*de_src buffer overflow !!");
668
669                         if (*de_src != NULL)
670                                 free(*de_src);
671
672                         if (de_temp != NULL)
673                                 free(de_temp);
674
675                         if (value != NULL)
676                                 free(value);
677
678                         return 0;
679                 }
680
681                 /*
682                  *      find "ENCODING=" since "\r\n" agina
683                  */
684                 src = line_breaker_loc;
685
686                 if (value != NULL)
687                         free(value);
688         }
689
690         len = 0;
691         len = g_strlcat(*de_src, src, (src_len + 1));
692         if (len >= (src_len + 1)) {
693                 _DEBUG_ERROR("*de_src buffer overflow !!");
694
695                 if (*de_src != NULL)
696                         free(*de_src);
697
698                 if (de_temp != NULL)
699                         free(de_temp);
700
701                 return 0;
702         }
703
704         *de_src_len = strlen(*de_src);
705         _DEBUG_INFO("[encoding_util] changed src : \n%s ( %d ) \n", *de_src, *de_src_len);
706
707         if (de_temp != NULL)
708                 free(de_temp);
709
710         _DEBUG_INFO("[encoding_util] End \n");
711
712         _EXTERN_FUNC_EXIT;
713
714         return 1;
715 }
716
717 int check_encoding_data(const char *data)
718 {
719         _EXTERN_FUNC_ENTER;
720
721         if (strstr(data, "ENCODING=") != NULL) {
722                 _DEBUG_INFO("[encoding_util] exist encoding data !! \n");
723                 _EXTERN_FUNC_EXIT;
724                 return 1;
725         } else {
726                 _DEBUG_INFO("[encoding_util] not exist encoding data !! \n");
727                 _EXTERN_FUNC_EXIT;
728                 return 0;
729         }
730 }
731
732 encoding_type_e find_encoding_type(const char *data)
733 {
734         _EXTERN_FUNC_ENTER;
735
736         _DEBUG_INFO("[encoding_util] Start !! \n");
737
738         encoding_type_e type = EN_TYPE_NONE;
739         if (strstr(data, "QUOTED-PRINTABLE") != NULL) {
740                 _DEBUG_INFO("[encoding_util] type : QP\n");
741                 type = EN_TYPE_QUOTED_PRINTABLE;
742         } else if (strstr(data, "BASE64") != NULL) {
743                 _DEBUG_INFO("[encoding_util] type : BASE64\n");
744                 type = EN_TYPE_BASE64;
745         } else {
746                 _DEBUG_INFO("[encoding_util] not supported type !! \n");
747         }
748
749         _DEBUG_INFO("[encoding_util] End !! \n");
750
751         _EXTERN_FUNC_EXIT;
752
753         return type;
754 }
755
756 int decode_value(encoding_type_e type, const char *value, int value_size, char **decode_str, int *decode_str_len)
757 {
758         _EXTERN_FUNC_ENTER;
759
760         retvm_if(value == NULL, 0, "[encoding_util] value is NULL\n");
761
762         int res = 1;
763         const char *start_pos = NULL;
764         const char *cursor = NULL;
765         int semi_cnt = 0;
766         int len = 0;
767
768         /*
769          *      ex> value - =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
770          */
771         cursor = value;
772         start_pos = value;
773
774         while (*cursor != '\0') {
775                 if ((*cursor != ';') && (*(cursor + 1) != '\0')) {
776                         cursor++;
777                         continue;
778                 } else if (*cursor == ';') {
779                         semi_cnt++;
780                 }
781
782                 int data_size = 0;
783                 if (*cursor == ';')
784                         data_size = cursor - start_pos;
785                 else            /* case of [*(cursor+1)=='\0'] */
786                         data_size = cursor + 1 - start_pos;
787
788                 if (data_size == 0) {
789                         cursor++;
790                         start_pos++;
791                 } else {
792                         char *temp = (char *)malloc(sizeof(char) * (value_size + 1));
793                         if (temp == NULL) {
794                                 _DEBUG_ERROR("[encoding_util] malloc error !!");
795                                 return 0;
796                         }
797                         memset(temp, 0x00, sizeof(char) * (value_size + 1));
798                         memcpy(temp, start_pos, data_size);
799
800                         _DEBUG_INFO("[encoding_util] temp : %s \n", temp);
801
802                         char *decoding = 0;
803                         int decoding_len = 0;
804
805                         switch (type) {
806                         case EN_TYPE_QUOTED_PRINTABLE:
807                                 res = decode_qp(temp, data_size, &decoding, &decoding_len);
808                                 break;
809                         case EN_TYPE_BASE64:
810                                 res = decode_base64(temp, data_size, &decoding, &decoding_len);
811                                 break;
812                         default:
813                                 break;
814                         }
815
816                         if (temp != NULL)
817                                 free(temp);
818
819                         _DEBUG_INFO("[encoding_util] decoding : %s ( %d )\n", decoding, decoding_len);
820
821                         if (res != 1) {
822                                 _DEBUG_ERROR("[encoding_util] decoding error !! \n");
823
824                                 if (decoding != NULL)
825                                         free(decoding);
826
827                                 res = 0;
828                                 return res;
829                         }
830
831                         len = g_strlcat(*decode_str, decoding, TEMP_BUFFER_SIZE);
832                         if (len >= TEMP_BUFFER_SIZE) {
833                                 _DEBUG_ERROR("*decode_str buffer overflow !!");
834
835                                 if (decoding != NULL)
836                                         free(decoding);
837
838                                 res = 0;
839                                 return res;
840                         }
841
842                         _DEBUG_INFO("[encoding_util] *decode_str : %s\n", *decode_str);
843
844                         if (decoding != NULL)
845                                 free(decoding);
846
847                         cursor++;
848                         start_pos = cursor;
849                 }
850
851                 if (semi_cnt > 0) {
852                         int len = strlen(*decode_str);
853                         (*decode_str)[len] = ';';
854                         _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, strlen(*decode_str));
855                         semi_cnt--;
856                 }
857         }
858
859         *decode_str_len = strlen(*decode_str);
860
861         _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, *decode_str_len);
862
863         _DEBUG_INFO("[encoding_util] End !! \n");
864
865         _EXTERN_FUNC_EXIT;
866
867         return res;
868 }
869
870 static int _find_base(char ch)
871 {
872         _INNER_FUNC_ENTER;
873
874         int i = 0;
875         for (i = 0; i < 65; i++) {
876                 if (base64_table[i] == ch) {
877                         _DEBUG_TRACE("[encoding_util] End !! \n");
878                         _INNER_FUNC_EXIT;
879                         return i;
880                 }
881         }
882
883         return -1;
884 }