Mercurial > pidgin.yaz
annotate libpurple/protocols/oscar/encoding.c @ 31867:52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
encoding, what may cause problems with clients that using single-byte encoding,
while we using UTF-8 (for example: QIP2005).
This patch adds support for a comma-separated list of encodings.
for example:
{{{
utf-8,cp1251,us-ascii
}}}
This patch also fixes invalid encoding of buddy status and buddy info.
Fixes #13496.
committer: John Bailey <rekkanoryo@rekkanoryo.org>
author | loentar@google.com |
---|---|
date | Thu, 24 Mar 2011 22:37:29 +0000 |
parents | a8cc50c2279f |
children | 8b9e9c61d061 |
rev | line source |
---|---|
30816 | 1 /* |
2 * Purple's oscar protocol plugin | |
3 * This file is the legal property of its developers. | |
4 * Please see the AUTHORS file distributed alongside this file. | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
19 */ | |
20 | |
21 #include "encoding.h" | |
22 | |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
23 static gchar * |
31867
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
24 encoding_multi_convert_to_utf8(const gchar *text, gssize textlen, const gchar *encodings, GError **error, gboolean fallback) |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
25 { |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
26 gchar *utf8 = NULL; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
27 const gchar *begin = encodings; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
28 const gchar *end = NULL; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
29 gchar *curr_encoding = NULL; /* allocated buffer for encoding name */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
30 const gchar *curr_encoding_ro = NULL; /* read-only encoding name */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
31 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
32 if (!encodings) { |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
33 purple_debug_error("oscar", "encodings is NULL"); |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
34 return NULL; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
35 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
36 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
37 for (;;) |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
38 { |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
39 /* extract next encoding */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
40 end = strchr(begin, ','); |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
41 if (!end) { |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
42 curr_encoding_ro = begin; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
43 } else { /* allocate buffer for encoding */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
44 curr_encoding = g_strndup(begin, end - begin); |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
45 if (!curr_encoding) { |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
46 purple_debug_error("oscar", "Error allocating memory for encoding"); |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
47 break; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
48 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
49 curr_encoding_ro = curr_encoding; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
50 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
51 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
52 if (!g_ascii_strcasecmp(curr_encoding_ro, "utf-8") && g_utf8_validate(text, textlen, NULL)) { |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
53 break; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
54 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
55 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
56 utf8 = g_convert(text, textlen, "UTF-8", curr_encoding_ro, NULL, NULL, NULL); |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
57 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
58 if (!end) /* last occurence. do not free curr_encoding: buffer was'nt allocated */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
59 break; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
60 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
61 g_free(curr_encoding); /* free allocated buffer for encoding here */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
62 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
63 if (utf8) /* text was successfully converted */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
64 break; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
65 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
66 begin = end + 1; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
67 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
68 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
69 if (!utf8 && fallback) |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
70 { /* "begin" points to last encoding */ |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
71 utf8 = g_convert_with_fallback(text, textlen, "UTF-8", begin, "?", NULL, NULL, error); |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
72 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
73 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
74 return utf8; |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
75 } |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
76 |
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
77 static gchar * |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
78 encoding_extract(const char *encoding) |
30816 | 79 { |
80 char *begin, *end; | |
81 | |
30825
a4f579485ce6
encoding can be NULL in encoding_extract(); this is not an error and
ivan.komarov@soc.pidgin.im
parents:
30824
diff
changeset
|
82 if (encoding == NULL) { |
a4f579485ce6
encoding can be NULL in encoding_extract(); this is not an error and
ivan.komarov@soc.pidgin.im
parents:
30824
diff
changeset
|
83 return NULL; |
a4f579485ce6
encoding can be NULL in encoding_extract(); this is not an error and
ivan.komarov@soc.pidgin.im
parents:
30824
diff
changeset
|
84 } |
30816 | 85 |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
86 if (!g_str_has_prefix(encoding, "text/aolrtf; charset=") && |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
87 !g_str_has_prefix(encoding, "text/x-aolrtf; charset=") && |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
88 !g_str_has_prefix(encoding, "text/plain; charset=")) { |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
89 return g_strdup(encoding); |
30816 | 90 } |
91 | |
92 begin = strchr(encoding, '"'); | |
93 end = strrchr(encoding, '"'); | |
94 | |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
95 if ((begin == NULL) || (end == NULL) || (begin >= end)) { |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
96 return g_strdup(encoding); |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
97 } |
30816 | 98 |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
99 return g_strndup(begin+1, (end-1) - begin); |
30816 | 100 } |
101 | |
102 gchar * | |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
103 oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen) |
30816 | 104 { |
105 gchar *utf8 = NULL; | |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
106 const gchar *glib_encoding = NULL; |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
107 gchar *extracted_encoding = encoding_extract(encoding); |
31534
a8cc50c2279f
Remove trailing whitespace
Richard Laager <rlaager@wiktel.com>
parents:
31332
diff
changeset
|
108 |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
109 if (extracted_encoding == NULL || *extracted_encoding == '\0') { |
30816 | 110 purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n"); |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
111 } else if (!g_ascii_strcasecmp(extracted_encoding, "iso-8859-1")) { |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
112 glib_encoding = "iso-8859-1"; |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
113 } else if (!g_ascii_strcasecmp(extracted_encoding, "ISO-8859-1-Windows-3.1-Latin-1") || !g_ascii_strcasecmp(extracted_encoding, "us-ascii")) { |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
114 glib_encoding = "Windows-1252"; |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
115 } else if (!g_ascii_strcasecmp(extracted_encoding, "unicode-2-0")) { |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
116 glib_encoding = "UTF-16BE"; |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
117 } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) { |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
118 glib_encoding = extracted_encoding; |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
119 } |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
120 |
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
121 if (glib_encoding != NULL) { |
31867
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
122 utf8 = encoding_multi_convert_to_utf8(text, textlen, glib_encoding, NULL, FALSE); |
30816 | 123 } |
124 | |
125 /* | |
126 * If utf8 is still NULL then either the encoding is utf-8 or | |
127 * we have been unable to convert the text to utf-8 from the encoding | |
128 * that was specified. So we check if the text is valid utf-8 then | |
129 * just copy it. | |
130 */ | |
131 if (utf8 == NULL) { | |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
132 if (textlen != 0 && *text != '\0' && !g_utf8_validate(text, textlen, NULL)) |
30816 | 133 utf8 = g_strdup(_("(There was an error receiving this message. The buddy you are speaking with is probably using a different encoding than expected. If you know what encoding he is using, you can specify it in the advanced account options for your AIM/ICQ account.)")); |
134 else | |
135 utf8 = g_strndup(text, textlen); | |
136 } | |
137 | |
30819
ca90b6c27eb8
Refactored oscar_encoding_to_utf8().
ivan.komarov@soc.pidgin.im
parents:
30818
diff
changeset
|
138 g_free(extracted_encoding); |
30816 | 139 return utf8; |
140 } | |
141 | |
142 gchar * | |
143 oscar_utf8_try_convert(PurpleAccount *account, OscarData *od, const gchar *msg) | |
144 { | |
145 const char *charset = NULL; | |
146 char *ret = NULL; | |
147 | |
30834
a6511abec788
A couple of refactorings related to oscar_utf8_try_convert().
ivan.komarov@soc.pidgin.im
parents:
30830
diff
changeset
|
148 if (msg == NULL) |
a6511abec788
A couple of refactorings related to oscar_utf8_try_convert().
ivan.komarov@soc.pidgin.im
parents:
30830
diff
changeset
|
149 return NULL; |
a6511abec788
A couple of refactorings related to oscar_utf8_try_convert().
ivan.komarov@soc.pidgin.im
parents:
30830
diff
changeset
|
150 |
a6511abec788
A couple of refactorings related to oscar_utf8_try_convert().
ivan.komarov@soc.pidgin.im
parents:
30830
diff
changeset
|
151 if (g_utf8_validate(msg, -1, NULL)) |
a6511abec788
A couple of refactorings related to oscar_utf8_try_convert().
ivan.komarov@soc.pidgin.im
parents:
30830
diff
changeset
|
152 return g_strdup(msg); |
a6511abec788
A couple of refactorings related to oscar_utf8_try_convert().
ivan.komarov@soc.pidgin.im
parents:
30830
diff
changeset
|
153 |
30816 | 154 if (od->icq) |
155 charset = purple_account_get_string(account, "encoding", NULL); | |
156 | |
157 if(charset && *charset) | |
31867
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
158 ret = encoding_multi_convert_to_utf8(msg, -1, charset, NULL, FALSE); |
30816 | 159 |
160 if(!ret) | |
161 ret = purple_utf8_try_convert(msg); | |
162 | |
163 return ret; | |
164 } | |
165 | |
166 static gchar * | |
167 oscar_convert_to_utf8(const gchar *data, gsize datalen, const char *charsetstr, gboolean fallback) | |
168 { | |
169 gchar *ret = NULL; | |
170 GError *err = NULL; | |
171 | |
172 if ((charsetstr == NULL) || (*charsetstr == '\0')) | |
173 return NULL; | |
174 | |
175 if (g_ascii_strcasecmp("UTF-8", charsetstr)) { | |
31867
52801bade70e
Currently oscar (ICQ) protocol does not support comma-separated list of
loentar@google.com
parents:
31534
diff
changeset
|
176 ret = encoding_multi_convert_to_utf8(data, datalen, charsetstr, &err, fallback); |
30816 | 177 if (err != NULL) { |
178 purple_debug_warning("oscar", "Conversion from %s failed: %s.\n", | |
179 charsetstr, err->message); | |
180 g_error_free(err); | |
181 } | |
182 } else { | |
183 if (g_utf8_validate(data, datalen, NULL)) | |
184 ret = g_strndup(data, datalen); | |
185 else | |
186 purple_debug_warning("oscar", "String is not valid UTF-8.\n"); | |
187 } | |
188 | |
189 return ret; | |
190 } | |
191 | |
192 gchar * | |
30824
5661f30d1b8e
Got rid of receiving multipart messages over channel 1, which simplified the code
ivan.komarov@soc.pidgin.im
parents:
30819
diff
changeset
|
193 oscar_decode_im(PurpleAccount *account, const char *sourcebn, guint16 charset, const gchar *data, gsize datalen) |
30816 | 194 { |
195 gchar *ret = NULL; | |
196 /* charsetstr1 is always set to what the correct encoding should be. */ | |
197 const gchar *charsetstr1, *charsetstr2, *charsetstr3 = NULL; | |
198 | |
199 if ((datalen == 0) || (data == NULL)) | |
200 return NULL; | |
201 | |
202 if (charset == AIM_CHARSET_UNICODE) { | |
203 charsetstr1 = "UTF-16BE"; | |
204 charsetstr2 = "UTF-8"; | |
205 } else if (charset == AIM_CHARSET_LATIN_1) { | |
206 if ((sourcebn != NULL) && oscar_util_valid_name_icq(sourcebn)) | |
207 charsetstr1 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); | |
208 else | |
209 charsetstr1 = "ISO-8859-1"; | |
210 charsetstr2 = "UTF-8"; | |
211 } else if (charset == AIM_CHARSET_ASCII) { | |
212 /* Should just be "ASCII" */ | |
213 charsetstr1 = "ASCII"; | |
214 charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); | |
215 } else if (charset == 0x000d) { | |
216 /* iChat sending unicode over a Direct IM connection = UTF-8 */ | |
217 /* Mobile AIM client on multiple devices (including Blackberry Tour, Nokia 3100, and LG VX6000) = ISO-8859-1 */ | |
218 charsetstr1 = "UTF-8"; | |
219 charsetstr2 = "ISO-8859-1"; | |
220 charsetstr3 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); | |
221 } else { | |
222 /* Unknown, hope for valid UTF-8... */ | |
223 charsetstr1 = "UTF-8"; | |
224 charsetstr2 = purple_account_get_string(account, "encoding", OSCAR_DEFAULT_CUSTOM_ENCODING); | |
225 } | |
226 | |
30824
5661f30d1b8e
Got rid of receiving multipart messages over channel 1, which simplified the code
ivan.komarov@soc.pidgin.im
parents:
30819
diff
changeset
|
227 purple_debug_info("oscar", "Parsing IM, charset=0x%04hx, datalen=%" G_GSIZE_FORMAT ", choice1=%s, choice2=%s, choice3=%s\n", |
5661f30d1b8e
Got rid of receiving multipart messages over channel 1, which simplified the code
ivan.komarov@soc.pidgin.im
parents:
30819
diff
changeset
|
228 charset, datalen, charsetstr1, charsetstr2, (charsetstr3 ? charsetstr3 : "")); |
30816 | 229 |
230 ret = oscar_convert_to_utf8(data, datalen, charsetstr1, FALSE); | |
231 if (ret == NULL) { | |
232 if (charsetstr3 != NULL) { | |
233 /* Try charsetstr2 without allowing substitutions, then fall through to charsetstr3 if needed */ | |
234 ret = oscar_convert_to_utf8(data, datalen, charsetstr2, FALSE); | |
235 if (ret == NULL) | |
236 ret = oscar_convert_to_utf8(data, datalen, charsetstr3, TRUE); | |
237 } else { | |
238 /* Try charsetstr2, allowing substitutions */ | |
239 ret = oscar_convert_to_utf8(data, datalen, charsetstr2, TRUE); | |
240 } | |
241 } | |
242 if (ret == NULL) { | |
243 char *str, *salvage, *tmp; | |
244 | |
245 str = g_malloc(datalen + 1); | |
246 strncpy(str, data, datalen); | |
247 str[datalen] = '\0'; | |
248 salvage = purple_utf8_salvage(str); | |
249 tmp = g_strdup_printf(_("(There was an error receiving this message. Either you and %s have different encodings selected, or %s has a buggy client.)"), | |
250 sourcebn, sourcebn); | |
251 ret = g_strdup_printf("%s %s", salvage, tmp); | |
252 g_free(tmp); | |
253 g_free(str); | |
254 g_free(salvage); | |
255 } | |
256 | |
257 return ret; | |
258 } | |
259 | |
30827 | 260 static guint16 |
261 get_simplest_charset(const char *utf8) | |
262 { | |
30830
1f3ef11a9690
My esteemed mentor caught me red-handed. Thanks Mark!
ivan.komarov@soc.pidgin.im
parents:
30827
diff
changeset
|
263 while (*utf8) |
30827 | 264 { |
265 if ((unsigned char)(*utf8) > 0x7f) { | |
266 /* not ASCII! */ | |
267 return AIM_CHARSET_UNICODE; | |
268 } | |
30830
1f3ef11a9690
My esteemed mentor caught me red-handed. Thanks Mark!
ivan.komarov@soc.pidgin.im
parents:
30827
diff
changeset
|
269 utf8++; |
30827 | 270 } |
271 return AIM_CHARSET_ASCII; | |
272 } | |
273 | |
30818
9d386bf63eab
Stop using custom encodings (and LATIN-1, for that matter) for sending
ivan.komarov@soc.pidgin.im
parents:
30816
diff
changeset
|
274 gchar * |
30827 | 275 oscar_encode_im(const gchar *msg, gsize *result_len, guint16 *charset, gchar **charsetstr) |
30816 | 276 { |
30827 | 277 guint16 msg_charset = get_simplest_charset(msg); |
30818
9d386bf63eab
Stop using custom encodings (and LATIN-1, for that matter) for sending
ivan.komarov@soc.pidgin.im
parents:
30816
diff
changeset
|
278 if (charset != NULL) { |
9d386bf63eab
Stop using custom encodings (and LATIN-1, for that matter) for sending
ivan.komarov@soc.pidgin.im
parents:
30816
diff
changeset
|
279 *charset = msg_charset; |
30816 | 280 } |
30818
9d386bf63eab
Stop using custom encodings (and LATIN-1, for that matter) for sending
ivan.komarov@soc.pidgin.im
parents:
30816
diff
changeset
|
281 if (charsetstr != NULL) { |
9d386bf63eab
Stop using custom encodings (and LATIN-1, for that matter) for sending
ivan.komarov@soc.pidgin.im
parents:
30816
diff
changeset
|
282 *charsetstr = msg_charset == AIM_CHARSET_ASCII ? "us-ascii" : "unicode-2-0"; |
30816 | 283 } |
30818
9d386bf63eab
Stop using custom encodings (and LATIN-1, for that matter) for sending
ivan.komarov@soc.pidgin.im
parents:
30816
diff
changeset
|
284 return g_convert(msg, -1, msg_charset == AIM_CHARSET_ASCII ? "ASCII" : "UTF-16BE", "UTF-8", NULL, result_len, NULL); |
30816 | 285 } |