Revert manifest to default one
[profile/ivi/download-provider.git] / src / agent / download-agent-encoding.c
1 /*
2  * Download Agent
3  *
4  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * @file        download-agent-encoding.c
21  * @brief       Utilities to manipulate encoding and charset
22  * @author      Keunsoon Lee (keunsoon.lee@samsung.com)
23  */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <glib.h>
29
30 #include "download-agent-encoding.h"
31 #include "download-agent-debug.h"
32
33 da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
34         char **out_charset_type,
35         char *out_encoding_type,
36         char **out_raw_encoded_str);
37
38 da_bool_t is_base64_encoded_word(const char *in_str)
39 {
40         const char *haystack = DA_NULL;
41         char first_needle[8] = {0,};
42         char second_needle[8] = {0,};
43         char *found_str = DA_NULL;
44
45         if (!in_str) {
46                 DA_LOG_ERR(Default, "input string is NULL");
47                 return DA_FALSE;
48         }
49
50         haystack = in_str;
51         if (haystack[0] == '"') {
52                 snprintf(first_needle, sizeof(first_needle), "%s", "\"=?");     // "=?
53                 snprintf(second_needle, sizeof(second_needle), "%s", "?=\"");   // ?="
54         } else {
55                 snprintf(first_needle, sizeof(first_needle), "%s", "=?");       // =?
56                 snprintf(second_needle, sizeof(second_needle), "%s", "?=");     // ?=
57         }
58
59 //      DA_LOG(Default, "needle = [%s], haystack = [%s]", first_needle, haystack);
60
61         found_str = strstr(haystack, first_needle);
62         if (found_str) {
63                 if (found_str == haystack) {
64 //                      DA_LOG(Default, "Input string is starting with %s", needle);
65                         haystack = haystack + strlen(haystack) - strlen(second_needle);
66 //                      DA_LOG(Default, "second haystack is [%s]", haystack);
67                         if(!strcmp(haystack, second_needle))
68                                 return DA_TRUE;
69                 }
70         }
71         return DA_FALSE;
72 }
73
74 da_result_t decode_base64_encoded_str(const char *in_encoded_str,
75         char **out_decoded_ascii_str)
76 {
77         da_result_t ret = DA_RESULT_OK;
78
79         const char *org_str = DA_NULL;
80         char *charset_type = NULL;
81         char encoding_type = '\0';
82         char *raw_encoded_str = NULL;
83         char *decoded_str = NULL;
84         const gchar *g_encoded_text = NULL;
85         guchar *g_decoded_text = NULL;
86         gsize g_decoded_text_len = 0;
87
88         DA_LOG(Default, "input str = [%s]", in_encoded_str);
89
90         org_str = in_encoded_str;
91         if(!org_str) {
92                 DA_LOG_ERR(Default, "Input string is NULL");
93                 ret = DA_ERR_INVALID_ARGUMENT;
94                 goto ERR;
95         }
96
97         ret = _parsing_base64_encoded_str(org_str, &charset_type,
98                 &encoding_type, &raw_encoded_str);
99         if(ret != DA_RESULT_OK) {
100                 goto ERR;
101         }
102
103 //      DA_LOG(Default, "charset = [%s], encoding = [%c], raw = [%s]", charset_type, encoding_type, raw_encoded_str);
104
105         if(encoding_type != 'B') {
106                 DA_LOG_ERR(Default, "Encoded Word is not encoded with Base64, but %c. We can only handle Base64.", encoding_type);
107                 ret = DA_ERR_INVALID_ARGUMENT;
108                 goto ERR;
109         }
110
111         /*
112          * on glib/gtype.h
113          * typedef char   gchar;
114          * typedef unsigned char   guchar;
115          *
116          */
117         g_encoded_text = (const gchar*)raw_encoded_str;
118         g_decoded_text = g_base64_decode(g_encoded_text, &g_decoded_text_len);
119
120         if(g_decoded_text) {
121                 DA_LOG(Default, "g_decoded_text = [%s]", g_decoded_text);
122                 decoded_str = (char*)calloc(1, g_decoded_text_len+1);
123                 if(!decoded_str) {
124                         DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
125                         ret = DA_ERR_FAIL_TO_MEMALLOC;
126                         goto ERR;
127                 } else {
128                         memcpy(decoded_str, g_decoded_text, g_decoded_text_len);
129                 }
130         }
131         DA_LOG(Default, "decoded_str = [%s]", decoded_str);
132
133 ERR:
134         *out_decoded_ascii_str = decoded_str;
135
136         if(charset_type) {
137                 free(charset_type);
138                 charset_type = NULL;
139         }
140
141         if(raw_encoded_str) {
142                 free(raw_encoded_str);
143                 raw_encoded_str = NULL;
144         }
145
146         if(g_decoded_text) {
147                 g_free(g_decoded_text);
148         }
149
150         return ret;
151 }
152
153
154 da_result_t _parsing_base64_encoded_str(const char *in_encoded_str,
155         char **out_charset_type,
156         char *out_encoding_type,
157         char **out_raw_encoded_str)
158 {
159         da_result_t ret = DA_RESULT_OK;
160
161         const char *org_str = DA_NULL;  // e.g. =?UTF-8?B?7Jew7JWE7JmA7IKs7J6QLmpwZw==?=
162         char *charset_type = NULL;              // e.g. UTF-8
163         char encoding_type = '\0';              // e.g. B (means Base64)
164         char *raw_encoded_str = NULL;   // e.g. 7Jew7JWE7JmA7IKs7J6QLmpwZw==
165
166         char *haystack = DA_NULL;
167         char needle[8] = {0,};
168
169         char *wanted_str = DA_NULL;
170         int wanted_str_len = 0;
171         char *wanted_str_start = DA_NULL;
172         char *wanted_str_end = DA_NULL;
173
174         org_str = in_encoded_str;
175         if (!org_str) {
176                 DA_LOG_ERR(Default, "Input string is NULL");
177                 ret = DA_ERR_INVALID_ARGUMENT;
178                 goto ERR;
179         }
180
181         // strip "=?"
182         haystack = (char*)org_str;
183         snprintf(needle, sizeof(needle), "=?");
184         wanted_str_end = strstr(haystack, needle);
185         if (!wanted_str_end) {
186                 DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT");
187                 ret = DA_ERR_INVALID_ARGUMENT;
188                 goto ERR;
189         } else {
190                 wanted_str = wanted_str_end + strlen(needle);
191                 DA_LOG(Default, "strip [%s]", wanted_str);
192         }
193
194         // for charset
195         haystack = wanted_str_start = wanted_str;
196         needle[0] = '?';
197         wanted_str_end = strchr(haystack, needle[0]);
198         if (!wanted_str_end) {
199                 DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT");
200                 ret = DA_ERR_INVALID_ARGUMENT;
201                 goto ERR;
202         } else {
203                 wanted_str_len = wanted_str_end - wanted_str_start + 1;
204                 wanted_str = (char*)calloc(1, wanted_str_len+1);
205                 if (!wanted_str) {
206                         DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
207                         ret = DA_ERR_FAIL_TO_MEMALLOC;
208                         goto ERR;
209                 } else {
210                         snprintf(wanted_str, wanted_str_len+1, "%s", wanted_str_start);
211                         charset_type = wanted_str;
212                         wanted_str = DA_NULL;
213                 }
214
215                 DA_LOG(Default, "charset [%s]", charset_type);
216         }
217
218
219         // for encoding
220         encoding_type = *(++wanted_str_end);
221         DA_LOG(Default, "encoding [%c]", encoding_type);
222
223         // for raw encoded str
224         haystack = wanted_str_start = wanted_str_end + 1;
225         snprintf(needle, sizeof(needle), "?=");
226         wanted_str_end = strstr(haystack, needle);
227         if (!wanted_str_end) {
228                 DA_LOG_ERR(Default, "DA_ERR_INVALID_ARGUMENT");
229                 ret = DA_ERR_INVALID_ARGUMENT;
230                 goto ERR;
231         } else {
232                 wanted_str_len = wanted_str_end - wanted_str_start + 1;
233                 wanted_str = (char*)calloc(1, wanted_str_len+1);
234                 if (!wanted_str) {
235                         DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
236                         ret = DA_ERR_FAIL_TO_MEMALLOC;
237                         goto ERR;
238                 } else {
239                         snprintf(wanted_str, wanted_str_len+1, "%s", wanted_str_start);
240                         raw_encoded_str = wanted_str;
241                         wanted_str = NULL;
242                 }
243
244                 DA_LOG(Default, "raw encoded str [%s]", raw_encoded_str);
245         }
246
247 ERR:
248         if (ret != DA_RESULT_OK) {
249                 if (charset_type) {
250                         free(charset_type);
251                         charset_type = NULL;
252                 }
253         }
254
255         *out_charset_type = charset_type;
256         *out_encoding_type = encoding_type;
257         *out_raw_encoded_str = raw_encoded_str;
258
259         return ret;
260 }
261
262 void decode_url_encoded_str(const char *in_encoded_str, char **out_str)
263 {
264     char *in = NULL;
265         char *out = NULL;
266         *out_str = calloc(1, strlen(in_encoded_str) + 1);
267         if (*out_str == NULL)
268                 return;
269     out = *out_str;
270     in = (char *)in_encoded_str;
271         while (*in)
272         {
273                 if (*in == '%') {
274                         int hex = 0;
275                         in++;
276                         if (sscanf(in, "%2x", &hex) <= 0) {
277                                 return;
278                         } else {
279                                 *out = hex;
280                                 in++;
281                         }
282                 } else if (*in == '+') {
283                         *out = ' ';
284                 } else {
285                         *out = *in;
286                 }
287                 in++;
288                 out++;
289         }
290 }
291