Mercurial > pidgin.yaz
annotate src/protocols/yahoo/util.c @ 13598:41e40b323dc3
[gaim-migrate @ 15984]
Previously our file transfer dialog showed "time elapsed" as the current
time minus the time when the transfer was added to the ft dialog.
When sending a file, the transfer is added when you offer the file to
the remote user, not when the transfer actually starts. This meant the
"time elapsed" was longer than it should have been, which threw off the
transfer rate.
This should fix that.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 09 Apr 2006 17:38:38 +0000 |
parents | f4e58e94ced3 |
children | 76d8b0032f50 |
rev | line source |
---|---|
6513 | 1 /* |
2 * gaim | |
3 * | |
4 * Some code copyright 2003 Tim Ringenbach <omarvo@hotmail.com> | |
5 * (marv on irc.freenode.net) | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 * | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include "config.h" | |
25 #endif | |
26 | |
10023 | 27 #include "debug.h" |
28 #include "internal.h" | |
6513 | 29 #include "prpl.h" |
10023 | 30 |
7827 | 31 #include "yahoo.h" |
6513 | 32 |
6546 | 33 #include <string.h> |
34 | |
7827 | 35 /** |
36 * Encode some text to send to the yahoo server. | |
37 * | |
38 * @param gc The connection handle. | |
39 * @param str The null terminated utf8 string to encode. | |
40 * @param utf8 If not @c NULL, whether utf8 is okay or not. | |
41 * Even if it is okay, we may not use it. If we | |
42 * used it, we set this to @c TRUE, else to | |
43 * @c FALSE. If @c NULL, false is assumed, and | |
44 * it is not dereferenced. | |
45 * @return The g_malloced string in the appropriate encoding. | |
46 */ | |
47 char *yahoo_string_encode(GaimConnection *gc, const char *str, gboolean *utf8) | |
48 { | |
9164 | 49 struct yahoo_data *yd = gc->proto_data; |
7827 | 50 char *ret; |
10504 | 51 const char *to_codeset; |
7827 | 52 |
9164 | 53 if (yd->jp && utf8 && *utf8) |
54 *utf8 = FALSE; | |
55 | |
7827 | 56 if (utf8 && *utf8) /* FIXME: maybe don't use utf8 if it'll fit in latin1 */ |
57 return g_strdup(str); | |
58 | |
9164 | 59 if (yd->jp) |
60 to_codeset = "SHIFT_JIS"; | |
61 else | |
62 to_codeset = "ISO-8859-1"; | |
7827 | 63 |
8955 | 64 ret = g_convert_with_fallback(str, strlen(str), to_codeset, "UTF-8", "?", NULL, NULL, NULL); |
7827 | 65 if (ret) |
66 return ret; | |
67 else | |
68 return g_strdup(""); | |
69 } | |
70 | |
71 /** | |
72 * Decode some text received from the server. | |
73 * | |
74 * @param gc The gc handle. | |
75 * @param str The null terminated string to decode. | |
76 * @param utf8 Did the server tell us it was supposed to be utf8? | |
77 * @return The decoded, utf-8 string, which must be g_free()'d. | |
78 */ | |
79 char *yahoo_string_decode(GaimConnection *gc, const char *str, gboolean utf8) | |
80 { | |
9164 | 81 struct yahoo_data *yd = gc->proto_data; |
7827 | 82 char *ret; |
83 char *from_codeset; | |
84 | |
85 if (utf8) { | |
86 if (g_utf8_validate(str, -1, NULL)) | |
87 return g_strdup(str); | |
88 } | |
89 | |
9164 | 90 if (yd->jp) |
91 from_codeset = "SHIFT_JIS"; | |
92 else | |
93 from_codeset = "ISO-8859-1"; | |
7827 | 94 |
95 ret = g_convert_with_fallback(str, strlen(str), "UTF-8", from_codeset, NULL, NULL, NULL, NULL); | |
96 | |
97 if (ret) | |
98 return ret; | |
99 else | |
100 return g_strdup(""); | |
101 } | |
102 | |
6513 | 103 /* |
104 * I found these on some website but i don't know that they actually | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
8533
diff
changeset
|
105 * work (or are supposed to work). I didn't implement them yet. |
6513 | 106 * |
107 * [0;30m ---black | |
108 * [1;37m ---white | |
109 * [0;37m ---tan | |
110 * [0;38m ---light black | |
111 * [1;39m ---dark blue | |
112 * [0;32m ---green | |
113 * [0;33m ---yellow | |
114 * [0;35m ---pink | |
115 * [1;35m ---purple | |
116 * [1;30m ---light blue | |
117 * [0;31m ---red | |
118 * [0;34m ---blue | |
119 * [0;36m ---aqua | |
120 * (shift+comma)lyellow(shift+period) ---light yellow | |
121 * (shift+comma)lgreen(shift+period) ---light green | |
122 [2;30m <--white out | |
123 */ | |
124 | |
125 static GHashTable *ht = NULL; | |
126 | |
127 void yahoo_init_colorht() | |
128 { | |
129 ht = g_hash_table_new(g_str_hash, g_str_equal); | |
6629 | 130 /* the numbers in comments are what gyach uses, but i think they're incorrect */ |
6513 | 131 g_hash_table_insert(ht, "30", "<FONT COLOR=\"#000000\">"); /* black */ |
132 g_hash_table_insert(ht, "31", "<FONT COLOR=\"#0000FF\">"); /* blue */ | |
133 g_hash_table_insert(ht, "32", "<FONT COLOR=\"#008080\">"); /* cyan */ /* 00b2b2 */ | |
134 g_hash_table_insert(ht, "33", "<FONT COLOR=\"#808080\">"); /* gray */ /* 808080 */ | |
135 g_hash_table_insert(ht, "34", "<FONT COLOR=\"#008000\">"); /* green */ /* 00c200 */ | |
136 g_hash_table_insert(ht, "35", "<FONT COLOR=\"#FF0080\">"); /* pink */ /* ffafaf */ | |
137 g_hash_table_insert(ht, "36", "<FONT COLOR=\"#800080\">"); /* purple */ /* b200b2 */ | |
138 g_hash_table_insert(ht, "37", "<FONT COLOR=\"#FF8000\">"); /* orange */ /* ffff00 */ | |
139 g_hash_table_insert(ht, "38", "<FONT COLOR=\"#FF0000\">"); /* red */ | |
140 g_hash_table_insert(ht, "39", "<FONT COLOR=\"#808000\">"); /* olive */ /* 546b50 */ | |
141 | |
142 g_hash_table_insert(ht, "1", "<B>"); | |
143 g_hash_table_insert(ht, "x1", "</B>"); | |
144 g_hash_table_insert(ht, "2", "<I>"); | |
145 g_hash_table_insert(ht, "x2", "</I>"); | |
146 g_hash_table_insert(ht, "4", "<U>"); | |
147 g_hash_table_insert(ht, "x4", "</U>"); | |
148 | |
6629 | 149 /* these just tell us the text they surround is supposed |
150 * to be a link. gaim figures that out on its own so we | |
151 * just ignore it. | |
152 */ | |
153 g_hash_table_insert(ht, "l", ""); /* link start */ | |
154 g_hash_table_insert(ht, "xl", ""); /* link end */ | |
155 | |
6513 | 156 g_hash_table_insert(ht, "<black>", "<FONT COLOR=\"#000000\">"); |
157 g_hash_table_insert(ht, "<blue>", "<FONT COLOR=\"#0000FF\">"); | |
158 g_hash_table_insert(ht, "<cyan>", "<FONT COLOR=\"#008284\">"); | |
159 g_hash_table_insert(ht, "<gray>", "<FONT COLOR=\"#848284\">"); | |
160 g_hash_table_insert(ht, "<green>", "<FONT COLOR=\"#008200\">"); | |
161 g_hash_table_insert(ht, "<pink>", "<FONT COLOR=\"#FF0084\">"); | |
162 g_hash_table_insert(ht, "<purple>", "<FONT COLOR=\"#840084\">"); | |
163 g_hash_table_insert(ht, "<orange>", "<FONT COLOR=\"#FF8000\">"); | |
164 g_hash_table_insert(ht, "<red>", "<FONT COLOR=\"#FF0000\">"); | |
165 g_hash_table_insert(ht, "<yellow>", "<FONT COLOR=\"#848200\">"); | |
166 | |
167 g_hash_table_insert(ht, "</black>", "</FONT>"); | |
168 g_hash_table_insert(ht, "</blue>", "</FONT>"); | |
169 g_hash_table_insert(ht, "</cyan>", "</FONT>"); | |
170 g_hash_table_insert(ht, "</gray>", "</FONT>"); | |
171 g_hash_table_insert(ht, "</green>", "</FONT>"); | |
172 g_hash_table_insert(ht, "</pink>", "</FONT>"); | |
173 g_hash_table_insert(ht, "</purple>", "</FONT>"); | |
174 g_hash_table_insert(ht, "</orange>", "</FONT>"); | |
175 g_hash_table_insert(ht, "</red>", "</FONT>"); | |
176 g_hash_table_insert(ht, "</yellow>", "</FONT>"); | |
177 | |
178 /* remove these once we have proper support for <FADE> and <ALT> */ | |
179 g_hash_table_insert(ht, "</fade>", ""); | |
180 g_hash_table_insert(ht, "</alt>", ""); | |
8375 | 181 |
182 /* these are the normal html yahoo sends (besides <font>). | |
183 * anything else will get turned into <tag>, so if I forgot | |
184 * about something, please add it. Why Yahoo! has to send unescaped | |
185 * <'s and >'s that aren't supposed to be html is beyond me. | |
186 */ | |
187 g_hash_table_insert(ht, "<b>", "<b>"); | |
188 g_hash_table_insert(ht, "<i>", "<i>"); | |
189 g_hash_table_insert(ht, "<u>", "<u>"); | |
190 | |
191 g_hash_table_insert(ht, "</b>", "</b>"); | |
192 g_hash_table_insert(ht, "</i>", "</i>"); | |
193 g_hash_table_insert(ht, "</u>", "</u>"); | |
8440 | 194 g_hash_table_insert(ht, "</font>", "</font>"); |
6513 | 195 } |
196 | |
197 void yahoo_dest_colorht() | |
198 { | |
199 g_hash_table_destroy(ht); | |
200 } | |
201 | |
6629 | 202 static int point_to_html(int x) |
203 { | |
204 if (x < 9) | |
205 return 1; | |
206 if (x < 11) | |
207 return 2; | |
208 if (x < 13) | |
209 return 3; | |
210 if (x < 17) | |
211 return 4; | |
212 if (x < 25) | |
213 return 5; | |
214 if (x < 35) | |
215 return 6; | |
216 return 7; | |
217 } | |
10380 | 218 |
219 /* The Yahoo size tag is actually an absz tag; convert it to an HTML size, and include both tags */ | |
6629 | 220 static void _font_tags_fix_size(GString *tag, GString *dest) |
221 { | |
222 char *x, *end; | |
223 int size; | |
224 | |
225 if (((x = strstr(tag->str, "size"))) && ((x = strchr(tag->str, '=')))) { | |
226 while (*x && !g_ascii_isdigit(*x)) | |
227 x++; | |
228 if (*x) { | |
10380 | 229 int htmlsize; |
230 | |
6629 | 231 size = strtol(x, &end, 10); |
10380 | 232 htmlsize = point_to_html(size); |
6629 | 233 g_string_append_len(dest, tag->str, x - tag->str); |
10380 | 234 g_string_append_printf(dest, "%d", htmlsize); |
235 g_string_append_printf(dest, "\" absz=\"%d", size); | |
6629 | 236 g_string_append(dest, end); |
237 } else { | |
238 g_string_append(dest, tag->str); | |
239 return; | |
240 } | |
241 } else { | |
242 g_string_append(dest, tag->str); | |
243 return; | |
244 } | |
245 } | |
246 | |
247 char *yahoo_codes_to_html(const char *x) | |
6513 | 248 { |
249 GString *s, *tmp; | |
6629 | 250 int i, j, xs, nomoreendtags = 0; /* s/endtags/closinganglebrackets */ |
6513 | 251 char *match, *ret; |
252 | |
253 s = g_string_sized_new(strlen(x)); | |
254 | |
255 for (i = 0, xs = strlen(x); i < xs; i++) { | |
256 if ((x[i] == 0x1b) && (x[i+1] == '[')) { | |
257 j = i + 1; | |
258 | |
259 while (j++ < xs) { | |
260 if (x[j] != 'm') | |
261 continue; | |
262 else { | |
263 tmp = g_string_new_len(x + i + 2, j - i - 2); | |
6621 | 264 if (tmp->str[0] == '#') |
6513 | 265 g_string_append_printf(s, "<FONT COLOR=\"%s\">", tmp->str); |
6546 | 266 else if ((match = (char *) g_hash_table_lookup(ht, tmp->str))) |
6513 | 267 g_string_append(s, match); |
268 else { | |
269 gaim_debug(GAIM_DEBUG_ERROR, "yahoo", | |
270 "Unknown ansi code 'ESC[%sm'.\n", tmp->str); | |
271 g_string_free(tmp, TRUE); | |
272 break; | |
273 } | |
274 | |
275 i = j; | |
276 g_string_free(tmp, TRUE); | |
277 break; | |
278 } | |
279 } | |
280 | |
281 } else if (!nomoreendtags && (x[i] == '<')) { | |
6629 | 282 j = i; |
6513 | 283 |
284 while (j++ < xs) { | |
285 if (x[j] != '>') | |
286 if (j == xs) { | |
8375 | 287 g_string_append(s, "<"); |
6513 | 288 nomoreendtags = 1; |
289 } | |
290 else | |
291 continue; | |
292 else { | |
293 tmp = g_string_new_len(x + i, j - i + 1); | |
294 g_string_ascii_down(tmp); | |
295 | |
6546 | 296 if ((match = (char *) g_hash_table_lookup(ht, tmp->str))) |
6513 | 297 g_string_append(s, match); |
6629 | 298 else if (!strncmp(tmp->str, "<fade ", 6) || |
299 !strncmp(tmp->str, "<alt ", 5) || | |
300 !strncmp(tmp->str, "<snd ", 5)) { | |
6513 | 301 |
6629 | 302 /* remove this if gtkimhtml ever supports any of these */ |
6513 | 303 i = j; |
304 g_string_free(tmp, TRUE); | |
305 break; | |
306 | |
6629 | 307 } else if (!strncmp(tmp->str, "<font ", 6)) { |
308 _font_tags_fix_size(tmp, s); | |
6513 | 309 } else { |
8375 | 310 g_string_append(s, "<"); |
6513 | 311 g_string_free(tmp, TRUE); |
312 break; | |
313 } | |
314 | |
315 i = j; | |
316 g_string_free(tmp, TRUE); | |
317 break; | |
318 } | |
319 | |
320 } | |
321 | |
322 } else { | |
8375 | 323 if (x[i] == '<') |
324 g_string_append(s, "<"); | |
325 else if (x[i] == '>') | |
326 g_string_append(s, ">"); | |
8440 | 327 else if (x[i] == '&') |
328 g_string_append(s, "&"); | |
329 else if (x[i] == '"') | |
330 g_string_append(s, """); | |
8375 | 331 else |
332 g_string_append_c(s, x[i]); | |
6513 | 333 } |
334 } | |
335 | |
336 ret = s->str; | |
337 g_string_free(s, FALSE); | |
6629 | 338 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "yahoo_codes_to_html: Returning string: '%s'.\n", ret); |
6513 | 339 return ret; |
340 } | |
6629 | 341 |
342 /* borrowed from gtkimhtml */ | |
343 #define MAX_FONT_SIZE 7 | |
10899 | 344 #define POINT_SIZE(x) (_point_sizes [MIN ((x > 0 ? x : 1), MAX_FONT_SIZE) - 1]) |
6629 | 345 static gint _point_sizes [] = { 8, 10, 12, 14, 20, 30, 40 }; |
346 | |
347 enum fatype { size, color, face, junk }; | |
348 typedef struct { | |
349 enum fatype type; | |
350 union { | |
351 int size; | |
352 char *color; | |
353 char *face; | |
354 char *junk; | |
355 } u; | |
356 } fontattr; | |
357 | |
358 static void fontattr_free(fontattr *f) | |
359 { | |
360 if (f->type == color) | |
361 g_free(f->u.color); | |
362 else if (f->type == face) | |
363 g_free(f->u.face); | |
364 g_free(f); | |
365 } | |
366 | |
367 static void yahoo_htc_queue_cleanup(GQueue *q) | |
368 { | |
369 char *tmp; | |
370 | |
371 while ((tmp = g_queue_pop_tail(q))) | |
372 g_free(tmp); | |
373 g_queue_free(q); | |
374 } | |
375 | |
376 static void _parse_font_tag(const char *src, GString *dest, int *i, int *j, | |
377 int len, GQueue *colors, GQueue *tags, GQueue *ftattr) | |
378 { | |
379 | |
380 int m, n, vstart; | |
381 gboolean quote = 0, done = 0; | |
382 | |
383 m = *j; | |
384 | |
385 while (1) { | |
386 m++; | |
387 | |
388 if (m >= len) { | |
389 g_string_append(dest, &src[*i]); | |
390 *i = len; | |
391 break; | |
392 } | |
393 | |
394 if (src[m] == '=') { | |
395 n = vstart = m; | |
396 while (1) { | |
397 n++; | |
398 | |
399 if (n >= len) { | |
400 m = n; | |
401 break; | |
402 } | |
403 | |
6631 | 404 if (src[n] == '"') { |
6629 | 405 if (!quote) { |
406 quote = 1; | |
407 vstart = n; | |
408 continue; | |
409 } else { | |
410 done = 1; | |
411 } | |
6631 | 412 } |
6629 | 413 |
414 if (!quote && ((src[n] == ' ') || (src[n] == '>'))) | |
415 done = 1; | |
416 | |
417 if (done) { | |
418 if (!g_ascii_strncasecmp(&src[*j+1], "FACE", m - *j - 1)) { | |
419 fontattr *f; | |
420 | |
421 f = g_new(fontattr, 1); | |
422 f->type = face; | |
423 f->u.face = g_strndup(&src[vstart+1], n-vstart-1); | |
424 if (!ftattr) | |
425 ftattr = g_queue_new(); | |
426 g_queue_push_tail(ftattr, f); | |
427 m = n; | |
428 break; | |
429 } else if (!g_ascii_strncasecmp(&src[*j+1], "SIZE", m - *j - 1)) { | |
430 fontattr *f; | |
431 | |
432 f = g_new(fontattr, 1); | |
433 f->type = size; | |
434 f->u.size = POINT_SIZE(strtol(&src[vstart+1], NULL, 10)); | |
435 if (!ftattr) | |
436 ftattr = g_queue_new(); | |
437 g_queue_push_tail(ftattr, f); | |
438 m = n; | |
439 break; | |
440 } else if (!g_ascii_strncasecmp(&src[*j+1], "COLOR", m - *j - 1)) { | |
441 fontattr *f; | |
442 | |
443 f = g_new(fontattr, 1); | |
444 f->type = color; | |
445 f->u.color = g_strndup(&src[vstart+1], n-vstart-1); | |
446 if (!ftattr) | |
447 ftattr = g_queue_new(); | |
448 g_queue_push_head(ftattr, f); | |
449 m = n; | |
450 break; | |
451 } else { | |
452 fontattr *f; | |
453 | |
454 f = g_new(fontattr, 1); | |
455 f->type = junk; | |
456 f->u.junk = g_strndup(&src[*j+1], n-*j); | |
457 if (!ftattr) | |
458 ftattr = g_queue_new(); | |
459 g_queue_push_tail(ftattr, f); | |
460 m = n; | |
461 break; | |
462 } | |
463 | |
464 } | |
465 } | |
466 } | |
467 | |
468 if (src[m] == ' ') | |
469 *j = m; | |
470 | |
471 if (src[m] == '>') { | |
472 gboolean needendtag = 0; | |
473 fontattr *f; | |
474 GString *tmp = g_string_new(NULL); | |
475 char *colorstr; | |
476 | |
477 if (!g_queue_is_empty(ftattr)) { | |
478 while ((f = g_queue_pop_tail(ftattr))) { | |
479 switch (f->type) { | |
480 case size: | |
481 if (!needendtag) { | |
482 needendtag = 1; | |
483 g_string_append(dest, "<font "); | |
484 } | |
485 | |
486 g_string_append_printf(dest, "size=\"%d\" ", f->u.size); | |
487 fontattr_free(f); | |
488 break; | |
489 case face: | |
490 if (!needendtag) { | |
491 needendtag = 1; | |
492 g_string_append(dest, "<font "); | |
493 } | |
494 | |
495 g_string_append_printf(dest, "face=\"%s\" ", f->u.face); | |
496 fontattr_free(f); | |
497 break; | |
498 case junk: | |
499 if (!needendtag) { | |
500 needendtag = 1; | |
501 g_string_append(dest, "<font "); | |
502 } | |
503 | |
504 g_string_append(dest, f->u.junk); | |
505 fontattr_free(f); | |
506 break; | |
507 | |
508 case color: | |
509 if (needendtag) { | |
510 g_string_append(tmp, "</font>"); | |
511 dest->str[dest->len-1] = '>'; | |
512 needendtag = 0; | |
513 } | |
514 | |
515 colorstr = g_queue_peek_tail(colors); | |
516 g_string_append(tmp, colorstr ? colorstr : "\033[#000000m"); | |
517 g_string_append_printf(dest, "\033[%sm", f->u.color); | |
518 g_queue_push_tail(colors, g_strdup_printf("\033[%sm", f->u.color)); | |
519 fontattr_free(f); | |
520 break; | |
521 } | |
522 } | |
523 | |
524 g_queue_free(ftattr); | |
525 ftattr = NULL; | |
526 | |
527 if (needendtag) { | |
528 dest->str[dest->len-1] = '>'; | |
529 g_queue_push_tail(tags, g_strdup("</font>")); | |
530 g_string_free(tmp, TRUE); | |
531 } else { | |
532 g_queue_push_tail(tags, tmp->str); | |
533 g_string_free(tmp, FALSE); | |
534 } | |
535 } | |
536 | |
537 *i = *j = m; | |
538 break; | |
539 } | |
540 } | |
541 | |
542 } | |
543 | |
544 char *yahoo_html_to_codes(const char *src) | |
545 { | |
6631 | 546 int i, j, len; |
6629 | 547 GString *dest; |
548 char *ret, *esc; | |
549 GQueue *colors, *tags; | |
550 GQueue *ftattr = NULL; | |
8440 | 551 gboolean no_more_specials = FALSE; |
6629 | 552 |
553 colors = g_queue_new(); | |
554 tags = g_queue_new(); | |
555 dest = g_string_sized_new(strlen(src)); | |
556 | |
557 for (i = 0, len = strlen(src); i < len; i++) { | |
558 | |
8440 | 559 if (!no_more_specials && src[i] == '<') { |
6629 | 560 j = i; |
561 | |
562 while (1) { | |
563 j++; | |
564 | |
565 if (j >= len) { /* no '>' */ | |
8440 | 566 g_string_append_c(dest, src[i]); |
567 no_more_specials = TRUE; | |
6629 | 568 break; |
569 } | |
570 | |
571 if (src[j] == '<') { | |
8440 | 572 /* FIXME: This doesn't convert outgoing entities. |
573 * However, I suspect this case may never | |
574 * happen anymore because of the entities. | |
575 */ | |
6629 | 576 g_string_append_len(dest, &src[i], j - i); |
577 i = j - 1; | |
578 if (ftattr) { | |
579 fontattr *f; | |
580 | |
581 while ((f = g_queue_pop_head(ftattr))) | |
582 fontattr_free(f); | |
583 g_queue_free(ftattr); | |
584 ftattr = NULL; | |
585 } | |
586 break; | |
587 } | |
588 | |
589 if (src[j] == ' ') { | |
590 if (!g_ascii_strncasecmp(&src[i+1], "BODY", j - i - 1)) { | |
591 char *t = strchr(&src[j], '>'); | |
592 if (!t) { | |
593 g_string_append(dest, &src[i]); | |
594 i = len; | |
595 break; | |
596 } else { | |
597 i = t - src; | |
598 break; | |
599 } | |
8533 | 600 } else if (!g_ascii_strncasecmp(&src[i+1], "A HREF=\"", j - i - 1)) { |
601 j += 7; | |
602 g_string_append(dest, "\033[lm"); | |
603 while (1) { | |
604 g_string_append_c(dest, src[j]); | |
605 if (++j >= len) { | |
8480 | 606 i = len; |
607 break; | |
608 } | |
8533 | 609 if (src[j] == '"') { |
610 g_string_append(dest, "\033[xlm"); | |
611 while (1) { | |
612 if (++j >= len) { | |
613 i = len; | |
614 break; | |
615 } | |
616 if (!g_ascii_strncasecmp(&src[j], "</A>", 4)) { | |
617 j += 3; | |
618 break; | |
619 } | |
620 } | |
621 i = j; | |
8480 | 622 break; |
623 } | |
624 } | |
6629 | 625 } else if (g_ascii_strncasecmp(&src[i+1], "FONT", j - i - 1)) { /* not interested! */ |
626 while (1) { | |
627 if (++j >= len) { | |
628 g_string_append(dest, &src[i]); | |
629 i = len; | |
630 break; | |
631 } | |
632 if (src[j] == '>') { | |
633 g_string_append_len(dest, &src[i], j - i + 1); | |
634 i = j; | |
635 break; | |
636 } | |
637 } | |
638 } else { /* yay we have a font tag */ | |
639 _parse_font_tag(src, dest, &i, &j, len, colors, tags, ftattr); | |
640 } | |
641 | |
642 break; | |
643 } | |
644 | |
645 if (src[j] == '>') { | |
8440 | 646 /* This has some problems like the FIXME for the |
647 * '<' case. and like that case, I suspect the case | |
648 * that this has problems is won't happen anymore anyway. | |
649 */ | |
6629 | 650 int sublen = j - i - 1; |
651 | |
652 if (sublen) { | |
653 if (!g_ascii_strncasecmp(&src[i+1], "B", sublen)) { | |
654 g_string_append(dest, "\033[1m"); | |
655 } else if (!g_ascii_strncasecmp(&src[i+1], "/B", sublen)) { | |
656 g_string_append(dest, "\033[x1m"); | |
657 } else if (!g_ascii_strncasecmp(&src[i+1], "I", sublen)) { | |
658 g_string_append(dest, "\033[2m"); | |
659 } else if (!g_ascii_strncasecmp(&src[i+1], "/I", sublen)) { | |
660 g_string_append(dest, "\033[x2m"); | |
661 } else if (!g_ascii_strncasecmp(&src[i+1], "U", sublen)) { | |
662 g_string_append(dest, "\033[4m"); | |
663 } else if (!g_ascii_strncasecmp(&src[i+1], "/U", sublen)) { | |
664 g_string_append(dest, "\033[x4m"); | |
8480 | 665 } else if (!g_ascii_strncasecmp(&src[i+1], "/A", sublen)) { |
666 g_string_append(dest, "\033[xlm"); | |
8455 | 667 } else if (!g_ascii_strncasecmp(&src[i+1], "BR", sublen)) { |
668 g_string_append_c(dest, '\n'); | |
6629 | 669 } else if (!g_ascii_strncasecmp(&src[i+1], "/BODY", sublen)) { |
670 /* mmm, </body> tags. *BURP* */ | |
671 } else if (!g_ascii_strncasecmp(&src[i+1], "/FONT", sublen) && g_queue_peek_tail(tags)) { | |
672 char *etag, *cl; | |
673 | |
674 etag = g_queue_pop_tail(tags); | |
675 if (etag) { | |
676 g_string_append(dest, etag); | |
677 if (!strcmp(etag, "</font>")) { | |
678 cl = g_queue_pop_tail(colors); | |
679 if (cl) | |
680 g_free(cl); | |
681 } | |
682 g_free(etag); | |
683 } | |
684 } else { | |
685 g_string_append_len(dest, &src[i], j - i + 1); | |
686 } | |
687 } else { | |
688 g_string_append_len(dest, &src[i], j - i + 1); | |
689 } | |
690 | |
691 i = j; | |
692 break; | |
693 } | |
694 | |
695 } | |
696 | |
697 } else { | |
8440 | 698 if (((len - i) >= 4) && !strncmp(&src[i], "<", 4)) { |
699 g_string_append_c(dest, '<'); | |
700 i += 3; | |
701 } else if (((len - i) >= 4) && !strncmp(&src[i], ">", 4)) { | |
702 g_string_append_c(dest, '>'); | |
703 i += 3; | |
704 } else if (((len - i) >= 5) && !strncmp(&src[i], "&", 4)) { | |
705 g_string_append_c(dest, '&'); | |
706 i += 4; | |
707 } else if (((len - i) >= 6) && !strncmp(&src[i], """, 4)) { | |
708 g_string_append_c(dest, '"'); | |
709 i += 5; | |
710 } else { | |
711 g_string_append_c(dest, src[i]); | |
712 } | |
6629 | 713 } |
714 } | |
715 | |
716 ret = dest->str; | |
717 g_string_free(dest, FALSE); | |
718 | |
719 esc = g_strescape(ret, NULL); | |
720 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "yahoo_html_to_codes: Returning string: '%s'.\n", esc); | |
721 g_free(esc); | |
722 | |
723 yahoo_htc_queue_cleanup(colors); | |
724 yahoo_htc_queue_cleanup(tags); | |
725 | |
726 return ret; | |
727 } |