Tizen 2.1 base
[platform/core/system/sync-agent.git] / src / fw-plugins / common-public / vcalendar / 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                         if(colon_loc_temp == NULL) {
552                                 _DEBUG_ERROR("[encoding_util] colon_loc_temp is NULL !!\n");
553                                 if(de_temp != NULL)
554                                         free(de_temp);
555                                 if (*de_src != NULL)
556                                         free(*de_src);
557                                 return 0;
558                         }
559                         line_breaker_loc = strstr(colon_loc_temp, line_breaker);        /* find "\r\n"'s location */
560                         if (line_breaker_loc > colon_loc_temp && !strncmp(line_breaker_loc - 1, "=", 1)) {
561                                 colon_loc_temp = line_breaker_loc + 1;
562                                 line_breaker_loc = 0;
563                         }
564                 }
565
566                 /*
567                  *      if find "ENCODING=" do strcat data until ":" to de_src
568                  */
569                 if (charset_loc != NULL) {
570                         if (start_decoding > charset_loc) {     /* CHARSET=UTF-8;ENCODING=abcxx: */
571                                 data_size = (charset_loc - 1) - src;
572                         } else {        /* ENCODING=abcxxx;CHARSET=UTF-8:       */
573                                 data_size = (start_decoding - 1) - src;
574                         }
575                 } else {
576                         data_size = (start_decoding - 1) - src;
577                 }
578
579                 char *temp = (char *)malloc(sizeof(char) * (data_size + 1));
580                 if (temp == NULL) {
581                         _DEBUG_ERROR("[encoding_util] malloc error !!");
582
583                         if (*de_src != NULL)
584                                 free(*de_src);
585
586                         if (de_temp != NULL)
587                                 free(de_temp);
588
589                         return 0;
590                 }
591                 memset(temp, 0x00, sizeof(char) * (data_size + 1));
592                 memcpy(temp, src, data_size);
593
594                 len = g_strlcat(*de_src, temp, (src_len + 1));
595                 if (len >= (src_len + 1)) {
596                         _DEBUG_ERROR("*de_src buffer overflow !!");
597
598                         if (*de_src != NULL)
599                                 free(*de_src);
600
601                         if (de_temp != NULL)
602                                 free(de_temp);
603
604                         if (temp != NULL)
605                                 free(temp);
606
607                         return 0;
608                 }
609
610                 (*de_src)[strlen(*de_src)] = ':';
611                 if (temp != NULL)
612                         free(temp);
613
614                 _DEBUG_INFO("[encoding_util] << *de_src >> \n %s\n", *de_src);
615
616                 /*
617                  *              copy data from ":" until "\r\n"(actual encoding stream)
618                  */
619                 data_size = line_breaker_loc - colon_loc;       /* from ':' until "\r\n" + '\0' */
620                 char *value = (char *)malloc(sizeof(char) * (data_size + 1));
621                 if (value == NULL) {
622                         _DEBUG_ERROR("[encoding_util] malloc error !!\n");
623
624                         if (*de_src != NULL)
625                                 free(*de_src);
626
627                         if (de_temp != NULL)
628                                 free(de_temp);
629
630                         return 0;
631                 }
632                 memset(value, 0x00, sizeof(char) * (data_size + 1));
633                 memcpy(value, ++colon_loc, data_size);  /* from ':' until "\r\n" */
634                 value[data_size] = '\0';
635                 _DEBUG_INFO("[encoding_util] data len is [%d] and value is [%s]\n\n", data_size, value);
636                 /*
637                  *      Get encoding type using data from "ENCODING=" to ":"
638                  */
639                 char type_check[TYPE_CHECK_BUF_SIZE] = { 0, };
640                 int type_check_size = colon_loc - start_decoding;
641                 strncpy(type_check, start_decoding, type_check_size);
642                 _DEBUG_INFO("[encoding_util] type check : %s\n", type_check);
643                 encoding_type_e type = find_encoding_type((const char *)type_check);
644
645                 /*
646                  *              Process decoding by passing the actual value and encoding type to decode_value()
647                  */
648                 de_temp_len = 0;
649                 memset(de_temp, 0x00, sizeof(char) * TEMP_BUFFER_SIZE); /* todo : temporary */
650
651                 res = decode_value(type, value, data_size, &de_temp, &de_temp_len);
652
653                 if (res != 1) {
654                         _DEBUG_ERROR("[encoding_util] decode_value error !!\n");
655
656                         if (*de_src != NULL)
657                                 free(*de_src);
658
659                         if (de_temp != NULL)
660                                 free(de_temp);
661
662                         if (value != NULL)
663                                 free(value);
664
665                         return 0;
666                 }
667
668                 /*
669                  *      Append decoded data to de_src
670                  */
671                 _DEBUG_INFO("[encoding_util] de_temp : %s\n", de_temp);
672                 len = 0;
673                 len = g_strlcat(*de_src, de_temp, (src_len + 1));
674                 if (len >= (src_len + 1)) {
675                         _DEBUG_ERROR("*de_src buffer overflow !!");
676
677                         if (*de_src != NULL)
678                                 free(*de_src);
679
680                         if (de_temp != NULL)
681                                 free(de_temp);
682
683                         if (value != NULL)
684                                 free(value);
685
686                         return 0;
687                 }
688
689                 /*
690                  *      find "ENCODING=" since "\r\n" agina
691                  */
692                 src = line_breaker_loc;
693
694                 if (value != NULL)
695                         free(value);
696         }
697
698         len = 0;
699         len = g_strlcat(*de_src, src, (src_len + 1));
700         if (len >= (src_len + 1)) {
701                 _DEBUG_ERROR("*de_src buffer overflow !!");
702
703                 if (*de_src != NULL)
704                         free(*de_src);
705
706                 if (de_temp != NULL)
707                         free(de_temp);
708
709                 return 0;
710         }
711
712         *de_src_len = strlen(*de_src);
713         _DEBUG_INFO("[encoding_util] changed src : \n%s ( %d ) \n", *de_src, *de_src_len);
714
715         if (de_temp != NULL)
716                 free(de_temp);
717
718         _DEBUG_INFO("[encoding_util] End \n");
719
720         _EXTERN_FUNC_EXIT;
721
722         return 1;
723 }
724
725 int check_encoding_data(const char *data)
726 {
727         _EXTERN_FUNC_ENTER;
728
729         if (strstr(data, "ENCODING=") != NULL) {
730                 _DEBUG_INFO("[encoding_util] exist encoding data !! \n");
731                 _EXTERN_FUNC_EXIT;
732                 return 1;
733         } else {
734                 _DEBUG_INFO("[encoding_util] not exist encoding data !! \n");
735                 _EXTERN_FUNC_EXIT;
736                 return 0;
737         }
738 }
739
740 encoding_type_e find_encoding_type(const char *data)
741 {
742         _EXTERN_FUNC_ENTER;
743
744         _DEBUG_INFO("[encoding_util] Start !! \n");
745
746         encoding_type_e type = EN_TYPE_NONE;
747         if (strstr(data, "QUOTED-PRINTABLE") != NULL) {
748                 _DEBUG_INFO("[encoding_util] type : QP\n");
749                 type = EN_TYPE_QUOTED_PRINTABLE;
750         } else if (strstr(data, "BASE64") != NULL) {
751                 _DEBUG_INFO("[encoding_util] type : BASE64\n");
752                 type = EN_TYPE_BASE64;
753         } else {
754                 _DEBUG_INFO("[encoding_util] not supported type !! \n");
755         }
756
757         _DEBUG_INFO("[encoding_util] End !! \n");
758
759         _EXTERN_FUNC_EXIT;
760
761         return type;
762 }
763
764 int decode_value(encoding_type_e type, const char *value, int value_size, char **decode_str, int *decode_str_len)
765 {
766         _EXTERN_FUNC_ENTER;
767
768         retvm_if(value == NULL, 0, "[encoding_util] value is NULL\n");
769
770         int res = 1;
771         const char *start_pos = NULL;
772         const char *cursor = NULL;
773         int semi_cnt = 0;
774         int len = 0;
775
776         /*
777          *      ex> value - =EA=B9=80;=EC=B2=A0=EC=88=98;;;\0
778          */
779         cursor = value;
780         start_pos = value;
781
782         while (*cursor != '\0') {
783                 if ((*cursor != ';') && (*(cursor + 1) != '\0')) {
784                         cursor++;
785                         continue;
786                 } else if (*cursor == ';') {
787                         semi_cnt++;
788                 }
789
790                 int data_size = 0;
791                 if (*cursor == ';')
792                         data_size = cursor - start_pos;
793                 else            /* case of [*(cursor+1)=='\0'] */
794                         data_size = cursor + 1 - start_pos;
795
796                 if (data_size == 0) {
797                         cursor++;
798                         start_pos++;
799                 } else {
800                         char *temp = (char *)malloc(sizeof(char) * (value_size + 1));
801                         if (temp == NULL) {
802                                 _DEBUG_ERROR("[encoding_util] malloc error !!");
803                                 return 0;
804                         }
805                         memset(temp, 0x00, sizeof(char) * (value_size + 1));
806                         memcpy(temp, start_pos, data_size);
807
808                         _DEBUG_INFO("[encoding_util] temp : %s \n", temp);
809
810                         char *decoding = 0;
811                         int decoding_len = 0;
812
813                         switch (type) {
814                         case EN_TYPE_QUOTED_PRINTABLE:
815                                 res = decode_qp(temp, data_size, &decoding, &decoding_len);
816                                 break;
817                         case EN_TYPE_BASE64:
818                                 res = decode_base64(temp, data_size, &decoding, &decoding_len);
819                                 break;
820                         default:
821                                 break;
822                         }
823
824                         if (temp != NULL)
825                                 free(temp);
826
827                         _DEBUG_INFO("[encoding_util] decoding : %s ( %d )\n", decoding, decoding_len);
828
829                         if (res != 1) {
830                                 _DEBUG_ERROR("[encoding_util] decoding error !! \n");
831
832                                 if (decoding != NULL)
833                                         free(decoding);
834
835                                 res = 0;
836                                 return res;
837                         }
838
839                         len = g_strlcat(*decode_str, decoding, TEMP_BUFFER_SIZE);
840                         if (len >= TEMP_BUFFER_SIZE) {
841                                 _DEBUG_ERROR("*decode_str buffer overflow !!");
842
843                                 if (decoding != NULL)
844                                         free(decoding);
845
846                                 res = 0;
847                                 return res;
848                         }
849
850                         _DEBUG_INFO("[encoding_util] *decode_str : %s\n", *decode_str);
851
852                         if (decoding != NULL)
853                                 free(decoding);
854
855                         cursor++;
856                         start_pos = cursor;
857                 }
858
859                 if (semi_cnt > 0) {
860                         int len = strlen(*decode_str);
861                         (*decode_str)[len] = ';';
862                         _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, strlen(*decode_str));
863                         semi_cnt--;
864                 }
865         }
866
867         *decode_str_len = strlen(*decode_str);
868
869         _DEBUG_INFO("[encoding_util] *decode_str : %s ( %d )\n", *decode_str, *decode_str_len);
870
871         _DEBUG_INFO("[encoding_util] End !! \n");
872
873         _EXTERN_FUNC_EXIT;
874
875         return res;
876 }
877
878 static int _find_base(char ch)
879 {
880         _INNER_FUNC_ENTER;
881
882         int i = 0;
883         for (i = 0; i < 65; i++) {
884                 if (base64_table[i] == ch) {
885                         _DEBUG_TRACE("[encoding_util] End !! \n");
886                         _INNER_FUNC_EXIT;
887                         return i;
888                 }
889         }
890
891         return -1;
892 }