4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * @file download-agent-encoding.c
21 * @brief Utilities to manipulate encoding and charset
22 * @author Keunsoon Lee (keunsoon.lee@samsung.com)
30 #include "download-agent-encoding.h"
31 #include "download-agent-debug.h"
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);
38 da_bool_t is_base64_encoded_word(const char *in_str)
40 const char *haystack = DA_NULL;
41 char first_needle[8] = {0,};
42 char second_needle[8] = {0,};
43 char *found_str = DA_NULL;
46 DA_LOG_ERR(Default, "input string is NULL");
51 if (haystack[0] == '"') {
52 snprintf(first_needle, sizeof(first_needle), "%s", "\"=?"); // "=?
53 snprintf(second_needle, sizeof(second_needle), "%s", "?=\""); // ?="
55 snprintf(first_needle, sizeof(first_needle), "%s", "=?"); // =?
56 snprintf(second_needle, sizeof(second_needle), "%s", "?="); // ?=
59 // DA_LOG(Default, "needle = [%s], haystack = [%s]", first_needle, haystack);
61 found_str = strstr(haystack, first_needle);
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))
74 da_result_t decode_base64_encoded_str(const char *in_encoded_str,
75 char **out_decoded_ascii_str)
77 da_result_t ret = DA_RESULT_OK;
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;
88 DA_LOG(Default, "input str = [%s]", in_encoded_str);
90 org_str = in_encoded_str;
92 DA_LOG_ERR(Default, "Input string is NULL");
93 ret = DA_ERR_INVALID_ARGUMENT;
97 ret = _parsing_base64_encoded_str(org_str, &charset_type,
98 &encoding_type, &raw_encoded_str);
99 if(ret != DA_RESULT_OK) {
103 // DA_LOG(Default, "charset = [%s], encoding = [%c], raw = [%s]", charset_type, encoding_type, raw_encoded_str);
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;
113 * typedef char gchar;
114 * typedef unsigned char guchar;
117 g_encoded_text = (const gchar*)raw_encoded_str;
118 g_decoded_text = g_base64_decode(g_encoded_text, &g_decoded_text_len);
121 DA_LOG(Default, "g_decoded_text = [%s]", g_decoded_text);
122 decoded_str = (char*)calloc(1, g_decoded_text_len+1);
124 DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
125 ret = DA_ERR_FAIL_TO_MEMALLOC;
128 memcpy(decoded_str, g_decoded_text, g_decoded_text_len);
131 DA_LOG(Default, "decoded_str = [%s]", decoded_str);
134 *out_decoded_ascii_str = decoded_str;
141 if(raw_encoded_str) {
142 free(raw_encoded_str);
143 raw_encoded_str = NULL;
147 g_free(g_decoded_text);
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)
159 da_result_t ret = DA_RESULT_OK;
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==
166 char *haystack = DA_NULL;
167 char needle[8] = {0,};
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;
174 org_str = in_encoded_str;
176 DA_LOG_ERR(Default, "Input string is NULL");
177 ret = DA_ERR_INVALID_ARGUMENT;
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;
190 wanted_str = wanted_str_end + strlen(needle);
191 DA_LOG(Default, "strip [%s]", wanted_str);
195 haystack = wanted_str_start = wanted_str;
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;
203 wanted_str_len = wanted_str_end - wanted_str_start + 1;
204 wanted_str = (char*)calloc(1, wanted_str_len+1);
206 DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
207 ret = DA_ERR_FAIL_TO_MEMALLOC;
210 snprintf(wanted_str, wanted_str_len+1, "%s", wanted_str_start);
211 charset_type = wanted_str;
212 wanted_str = DA_NULL;
215 DA_LOG(Default, "charset [%s]", charset_type);
220 encoding_type = *(++wanted_str_end);
221 DA_LOG(Default, "encoding [%c]", encoding_type);
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;
232 wanted_str_len = wanted_str_end - wanted_str_start + 1;
233 wanted_str = (char*)calloc(1, wanted_str_len+1);
235 DA_LOG_ERR(Default, "DA_ERR_FAIL_TO_MEMALLOC");
236 ret = DA_ERR_FAIL_TO_MEMALLOC;
239 snprintf(wanted_str, wanted_str_len+1, "%s", wanted_str_start);
240 raw_encoded_str = wanted_str;
244 DA_LOG(Default, "raw encoded str [%s]", raw_encoded_str);
248 if (ret != DA_RESULT_OK) {
255 *out_charset_type = charset_type;
256 *out_encoding_type = encoding_type;
257 *out_raw_encoded_str = raw_encoded_str;
262 void decode_url_encoded_str(const char *in_encoded_str, char **out_str)
266 *out_str = calloc(1, strlen(in_encoded_str) + 1);
267 if (*out_str == NULL)
270 in = (char *)in_encoded_str;
276 if (sscanf(in, "%2x", &hex) <= 0) {
282 } else if (*in == '+') {