Mercurial > pidgin.yaz
diff src/util.c @ 7820:8e60ddc28a22
[gaim-migrate @ 8472]
Mostly I just made the whole i18n-mime-email receiving thing for MSN
work without crashing. I did this by rewriting gaim_mime_decode_field()
It's not what you would call "efficient," but I mean, it only gets
called when you get new mail notificaion on MSN.
I think it's a lot easier to follow than revo/shx's version. Hopefully
that's not because I left out some critical element.
http://kingant.net/oscar/gaim/neat.png
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Tue, 09 Dec 2003 16:12:24 +0000 |
| parents | 622c9149609c |
| children | 1663c076a744 |
line wrap: on
line diff
--- a/src/util.c Tue Dec 09 03:07:29 2003 +0000 +++ b/src/util.c Tue Dec 09 16:12:24 2003 +0000 @@ -281,13 +281,15 @@ **************************************************************************/ #define OUT_CHARSET "utf-8" -char * +static char * gaim_mime_decode_word(const char *charset, const char *encoding, const char *str) { - /* TODO: We need to check for nulls */ char *decoded, *converted; int len = 0; + if ((charset == NULL) || (encoding == NULL) || (str == NULL)) + return NULL; + if (g_ascii_strcasecmp(encoding, "Q") == 0) gaim_quotedp_decode(str, &decoded, &len); else if (g_ascii_strcasecmp(encoding, "B") == 0) @@ -304,6 +306,57 @@ char * gaim_mime_decode_field(const char *str) { + GString *donedeal; + char *orig, *start, *end, *end_of_last, *tmp; + char **encoded_word; + char *charset, *encoding, *word; + + g_return_val_if_fail(str != NULL, NULL); + + orig = g_strdup(str); + donedeal = g_string_sized_new(strlen(orig)); + + /* One iteration per encoded-word */ + end_of_last = orig; + while ((start = strstr(end_of_last, "=?")) && (end = strstr(start, "?="))) { + /* Append everything from the end of the last encoded-word to the beginning of the next */ + tmp = g_strndup(end_of_last, (start - end_of_last)); + donedeal = g_string_append(donedeal, tmp); + g_free(tmp); + + /* Split the encoded word */ + tmp = g_strndup(start + 2, end - start - 4); + encoded_word = g_strsplit(tmp, "?", 3); + g_free(tmp); + charset = encoded_word[0]; + encoding = charset != NULL ? encoded_word[1] : NULL; + word = encoding != NULL ? encoded_word[2] : NULL; + g_strfreev(encoded_word); + + /* Convert the decoded word to utf8 and append it */ + tmp = gaim_mime_decode_word(charset, encoding, word); + donedeal = g_string_append(donedeal, tmp); + g_free(tmp); + + g_free(charset); + g_free(encoding); + g_free(word); + } + + /* Append everything from the end of the last encoded-word to the end of the string */ + tmp = g_strndup(end_of_last, ((orig + strlen(orig)) - end_of_last)); + donedeal = g_string_append(donedeal, tmp); + g_free(tmp); + + /* Free at last, free at last... */ + tmp = donedeal->str; + g_string_free(donedeal, FALSE); + g_free(orig); + + return tmp; + +#if 0 + /* This is revo/shx's version, and it caused coredumps for me */ char *cur, *mark; char *unencoded_start, *unencoded_end; char *charset, *encoding, *word, *decoded; @@ -312,13 +365,14 @@ n = new = g_malloc(strlen(str)); charset = word = NULL; +gaim_debug(GAIM_DEBUG_ERROR, "XXX", "new is %d\n", new); /* Here we will be looking for encoded words and if they seem to be * valid then decode them */ - for ( unencoded_start = cur = (char *)str; - (unencoded_end = cur = strstr(cur, "=?")); - unencoded_start = cur) - { + for (unencoded_start = cur = str; + (unencoded_end = cur = strstr(cur, "=?")); + unencoded_start = cur) { + int len; char *token; GQueue *tokens = g_queue_new(); @@ -343,6 +397,7 @@ } cur += 2; +gaim_debug(GAIM_DEBUG_ERROR, "XXX", "new is %d, this is probably different than above, that's bad\n", new); if ((tokens->length == 3) && (*mark == '=')) { len = unencoded_end - unencoded_start; @@ -378,6 +433,7 @@ n = strcpy(n, unencoded_start); return new; +#endif } /**************************************************************************
