comparison libpurple/protocols/oscar/encoding.c @ 32010:ce968e115c95

propagate from branch 'im.pidgin.cpw.masca.p2p' (head 33ca865dacb9e5bcf763d06f6a42cbaca337cc64) to branch 'im.pidgin.pidgin' (head 92f47f4e8b0cbb107fd97e1ab814d1cedbf109ad)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 06 May 2011 06:25:14 +0000
parents 52801bade70e
children 8b9e9c61d061
comparison
equal deleted inserted replaced
32009:f021d93a1f9b 32010:ce968e115c95
19 */ 19 */
20 20
21 #include "encoding.h" 21 #include "encoding.h"
22 22
23 static gchar * 23 static gchar *
24 encoding_multi_convert_to_utf8(const gchar *text, gssize textlen, const gchar *encodings, GError **error, gboolean fallback)
25 {
26 gchar *utf8 = NULL;
27 const gchar *begin = encodings;
28 const gchar *end = NULL;
29 gchar *curr_encoding = NULL; /* allocated buffer for encoding name */
30 const gchar *curr_encoding_ro = NULL; /* read-only encoding name */
31
32 if (!encodings) {
33 purple_debug_error("oscar", "encodings is NULL");
34 return NULL;
35 }
36
37 for (;;)
38 {
39 /* extract next encoding */
40 end = strchr(begin, ',');
41 if (!end) {
42 curr_encoding_ro = begin;
43 } else { /* allocate buffer for encoding */
44 curr_encoding = g_strndup(begin, end - begin);
45 if (!curr_encoding) {
46 purple_debug_error("oscar", "Error allocating memory for encoding");
47 break;
48 }
49 curr_encoding_ro = curr_encoding;
50 }
51
52 if (!g_ascii_strcasecmp(curr_encoding_ro, "utf-8") && g_utf8_validate(text, textlen, NULL)) {
53 break;
54 }
55
56 utf8 = g_convert(text, textlen, "UTF-8", curr_encoding_ro, NULL, NULL, NULL);
57
58 if (!end) /* last occurence. do not free curr_encoding: buffer was'nt allocated */
59 break;
60
61 g_free(curr_encoding); /* free allocated buffer for encoding here */
62
63 if (utf8) /* text was successfully converted */
64 break;
65
66 begin = end + 1;
67 }
68
69 if (!utf8 && fallback)
70 { /* "begin" points to last encoding */
71 utf8 = g_convert_with_fallback(text, textlen, "UTF-8", begin, "?", NULL, NULL, error);
72 }
73
74 return utf8;
75 }
76
77 static gchar *
24 encoding_extract(const char *encoding) 78 encoding_extract(const char *encoding)
25 { 79 {
26 char *begin, *end; 80 char *begin, *end;
27 81
28 if (encoding == NULL) { 82 if (encoding == NULL) {
49 oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen) 103 oscar_encoding_to_utf8(const char *encoding, const char *text, int textlen)
50 { 104 {
51 gchar *utf8 = NULL; 105 gchar *utf8 = NULL;
52 const gchar *glib_encoding = NULL; 106 const gchar *glib_encoding = NULL;
53 gchar *extracted_encoding = encoding_extract(encoding); 107 gchar *extracted_encoding = encoding_extract(encoding);
54 108
55 if (extracted_encoding == NULL || *extracted_encoding == '\0') { 109 if (extracted_encoding == NULL || *extracted_encoding == '\0') {
56 purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n"); 110 purple_debug_info("oscar", "Empty encoding, assuming UTF-8\n");
57 } else if (!g_ascii_strcasecmp(extracted_encoding, "iso-8859-1")) { 111 } else if (!g_ascii_strcasecmp(extracted_encoding, "iso-8859-1")) {
58 glib_encoding = "iso-8859-1"; 112 glib_encoding = "iso-8859-1";
59 } else if (!g_ascii_strcasecmp(extracted_encoding, "ISO-8859-1-Windows-3.1-Latin-1") || !g_ascii_strcasecmp(extracted_encoding, "us-ascii")) { 113 } else if (!g_ascii_strcasecmp(extracted_encoding, "ISO-8859-1-Windows-3.1-Latin-1") || !g_ascii_strcasecmp(extracted_encoding, "us-ascii")) {
63 } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) { 117 } else if (g_ascii_strcasecmp(extracted_encoding, "utf-8")) {
64 glib_encoding = extracted_encoding; 118 glib_encoding = extracted_encoding;
65 } 119 }
66 120
67 if (glib_encoding != NULL) { 121 if (glib_encoding != NULL) {
68 utf8 = g_convert(text, textlen, "UTF-8", glib_encoding, NULL, NULL, NULL); 122 utf8 = encoding_multi_convert_to_utf8(text, textlen, glib_encoding, NULL, FALSE);
69 } 123 }
70 124
71 /* 125 /*
72 * If utf8 is still NULL then either the encoding is utf-8 or 126 * If utf8 is still NULL then either the encoding is utf-8 or
73 * we have been unable to convert the text to utf-8 from the encoding 127 * we have been unable to convert the text to utf-8 from the encoding
99 153
100 if (od->icq) 154 if (od->icq)
101 charset = purple_account_get_string(account, "encoding", NULL); 155 charset = purple_account_get_string(account, "encoding", NULL);
102 156
103 if(charset && *charset) 157 if(charset && *charset)
104 ret = g_convert(msg, -1, "UTF-8", charset, NULL, NULL, NULL); 158 ret = encoding_multi_convert_to_utf8(msg, -1, charset, NULL, FALSE);
105 159
106 if(!ret) 160 if(!ret)
107 ret = purple_utf8_try_convert(msg); 161 ret = purple_utf8_try_convert(msg);
108 162
109 return ret; 163 return ret;
117 171
118 if ((charsetstr == NULL) || (*charsetstr == '\0')) 172 if ((charsetstr == NULL) || (*charsetstr == '\0'))
119 return NULL; 173 return NULL;
120 174
121 if (g_ascii_strcasecmp("UTF-8", charsetstr)) { 175 if (g_ascii_strcasecmp("UTF-8", charsetstr)) {
122 if (fallback) 176 ret = encoding_multi_convert_to_utf8(data, datalen, charsetstr, &err, fallback);
123 ret = g_convert_with_fallback(data, datalen, "UTF-8", charsetstr, "?", NULL, NULL, &err);
124 else
125 ret = g_convert(data, datalen, "UTF-8", charsetstr, NULL, NULL, &err);
126 if (err != NULL) { 177 if (err != NULL) {
127 purple_debug_warning("oscar", "Conversion from %s failed: %s.\n", 178 purple_debug_warning("oscar", "Conversion from %s failed: %s.\n",
128 charsetstr, err->message); 179 charsetstr, err->message);
129 g_error_free(err); 180 g_error_free(err);
130 } 181 }