# include <locale.h>
#endif
-#if HAVE_ICONV
-# include <iconv.h>
-#endif
-
#include "intl.h"
#include "codeconv.h"
#include "unmime.h"
JIS_AUXKANJI
} JISState;
-#define SUBST_CHAR '_'
+#define SUBST_CHAR 0x5f;
#define ESC '\033'
#define iseuckanji(c) \
}
}
+void conv_unreadable_utf8(gchar *str)
+{
+ register guchar *p = str;
+
+ while (*p != '\0') {
+ /* convert CR+LF -> LF */
+ printf("p %c (%d)\n", *p, *p);
+ if (*p == '\r' && *(p + 1) == '\n')
+ memmove(p, p + 1, strlen(p));
+ else if (((*p & 0xff) >= 0x7f && (*p & 0xff) <= 0x9f)
+ || *p == 0xfc)
+ *p = SUBST_CHAR;
+ p++;
+ }
+}
+
void conv_unreadable_locale(gchar *str)
{
switch (conv_get_current_charset()) {
case C_EUC_JP:
conv_unreadable_eucjp(str);
break;
+ case C_UTF_8:
+ conv_unreadable_utf8(str);
+ break;
default:
break;
}
gint conv_convert(CodeConverter *conv, gchar *outbuf, gint outlen,
const gchar *inbuf)
{
-#if HAVE_ICONV
if (conv->code_conv_func != conv_noconv)
conv->code_conv_func(outbuf, outlen, inbuf);
else {
g_free(str);
}
}
-#else /* !HAVE_ICONV */
- conv->code_conv_func(outbuf, outlen, inbuf);
-#endif
return 0;
}
return g_realloc(buf, strlen(buf) + 1);
}
-#if HAVE_ICONV
return conv_iconv_strdup(inbuf, src_code, dest_code);
-#else
- return g_strdup(inbuf);
-#endif /* HAVE_ICONV */
}
CodeConvFunc conv_get_code_conv_func(const gchar *src_charset_str,
return code_conv;
}
-#if HAVE_ICONV
gchar *conv_iconv_strdup(const gchar *inbuf,
- const gchar *src_code, const gchar *dest_code)
+ const gchar *isrc_code, const gchar *idest_code)
{
- iconv_t cd;
- const gchar *inbuf_p;
+ /* presumably GLib 2's function handles the conversion details,
+ * whether iconv is sitting below, or something else */
gchar *outbuf;
- gchar *outbuf_p;
- size_t in_size;
- size_t in_left;
- size_t out_size;
- size_t out_left;
- size_t n_conv;
- size_t len;
-
- if (!src_code)
- src_code = conv_get_outgoing_charset_str();
- if (!dest_code)
- dest_code = conv_get_current_charset_str();
+ gsize read_len, written_len;
+ gchar *src_code = (char *)conv_get_outgoing_charset_str();
+ gchar *dest_code = (char *)conv_get_current_charset_str();
+
+ if (isrc_code)
+ src_code = (char *)isrc_code;
+ if (idest_code)
+ dest_code = (char *)idest_code;
/* don't convert if current codeset is US-ASCII */
if (!strcasecmp(dest_code, CS_US_ASCII))
if (!strcasecmp(src_code, dest_code))
return g_strdup(inbuf);
- cd = iconv_open(dest_code, src_code);
- if (cd == (iconv_t)-1)
- return NULL;
-
- inbuf_p = inbuf;
- in_size = strlen(inbuf);
- in_left = in_size;
- out_size = (in_size + 1) * 2;
- outbuf = g_malloc(out_size);
- outbuf_p = outbuf;
- out_left = out_size;
-
-#define EXPAND_BUF() \
-{ \
- len = outbuf_p - outbuf; \
- out_size *= 2; \
- outbuf = g_realloc(outbuf, out_size); \
- outbuf_p = outbuf + len; \
- out_left = out_size - len; \
-}
+ /* FIXME: unchecked inbuf? Can't see at this level. */
+ outbuf = g_convert(inbuf, strlen(inbuf), dest_code, src_code,
+ &read_len, &written_len, NULL);
- while ((n_conv = iconv(cd, (ICONV_CONST gchar **)&inbuf_p, &in_left,
- &outbuf_p, &out_left)) == (size_t)-1) {
- if (EILSEQ == errno) {
- inbuf_p++;
- in_left--;
- if (out_left == 0) {
- EXPAND_BUF();
- }
- *outbuf_p++ = SUBST_CHAR;
- out_left--;
- } else if (EINVAL == errno) {
- break;
- } else if (E2BIG == errno) {
- EXPAND_BUF();
- } else {
- g_warning("conv_iconv_strdup(): %s\n",
- g_strerror(errno));
- break;
- }
- }
-
- while ((n_conv = iconv(cd, NULL, NULL, &outbuf_p, &out_left)) ==
- (size_t)-1) {
- if (E2BIG == errno) {
- EXPAND_BUF();
- } else {
- g_warning("conv_iconv_strdup(): %s\n",
- g_strerror(errno));
- break;
- }
- }
-
-#undef EXPAND_BUF
-
- len = outbuf_p - outbuf;
- outbuf = g_realloc(outbuf, len + 1);
- outbuf[len] = '\0';
-
- iconv_close(cd);
-
- return outbuf;
+ if (outbuf == NULL)
+ g_warning(_("Valid locale type set? (Currently: %s to %s)\n"),
+ src_code, dest_code);
+
+ return outbuf;
}
-#endif /* HAVE_ICONV */
static const struct {
CharSet charset;
}
}
-#if !HAVE_ICONV
- /* encoding conversion without iconv() is only supported
- on Japanese locale for now */
- if (out_charset == C_ISO_2022_JP)
- return out_charset;
- else
- return conv_get_current_charset();
-#endif
-
return out_charset;
}
const gchar *conv_get_current_locale(void)
{
- const gchar *cur_locale;
+ static const gchar *cur_locale = NULL;
+ if (cur_locale != NULL)
+ return cur_locale;
+
cur_locale = g_getenv("LC_ALL");
- if (!cur_locale) cur_locale = g_getenv("LC_CTYPE");
- if (!cur_locale) cur_locale = g_getenv("LANG");
- if (!cur_locale) cur_locale = setlocale(LC_CTYPE, NULL);
-
-/* debug_print("current locale: %s\n",
- cur_locale ? cur_locale : "(none)"); */
+ if (!cur_locale || !strlen(cur_locale))
+ cur_locale = g_getenv("LC_CTYPE");
+ if (!cur_locale || !strlen(cur_locale))
+ cur_locale = g_getenv("LANG");
+ if (!cur_locale || !strlen(cur_locale))
+ cur_locale = setlocale(LC_CTYPE, NULL);
+
+ if (cur_locale && strlen(cur_locale)) {
+ gchar *tmp = g_strdup(cur_locale);
+ cur_locale = g_strdup(tmp);
+ g_free(tmp);
+ }
return cur_locale;
}
void conv_unmime_header(gchar *outbuf, gint outlen, const gchar *str,
const gchar *charset)
{
- CharSet cur_charset;
const gchar *locale;
- cur_charset = conv_get_current_charset();
-
+ memset(outbuf, 0, outlen);
+
#warning FIXME_GTK2
/* Should we always ensure to convert? */
locale = conv_get_current_locale();
Xalloca(buf, buflen, return);
conv_anytodisp(buf, buflen, str);
unmime_header(outbuf, buf);
- } else
+ } else {
+ gchar *tmp;
unmime_header(outbuf, str);
+ if (outbuf && !g_utf8_validate(outbuf, -1, NULL)) {
+ tmp = conv_codeset_strdup(outbuf,
+ conv_get_current_charset_str(),
+ CS_UTF_8);
+ if (tmp) {
+ strncpy(outbuf, tmp, outlen-1);
+ g_free(tmp);
+ }
+ }
+ }
}
#define MAX_LINELEN 76
const guchar *srcp = src;
guchar *destp = dest;
gboolean use_base64;
-
+ gchar *testbuf;
+
if (MB_CUR_MAX > 1) {
use_base64 = TRUE;
mimesep_enc = "?B?";
mimesep_enc = "?Q?";
}
- cur_encoding = conv_get_current_charset_str();
- if (!strcmp(cur_encoding, CS_US_ASCII))
- cur_encoding = CS_ISO_8859_1;
+ cur_encoding = CS_UTF_8; /* gtk2 */
+
out_encoding = conv_get_outgoing_charset_str();
if (!strcmp(out_encoding, CS_US_ASCII))
out_encoding = CS_ISO_8859_1;
+ testbuf = conv_codeset_strdup(src, cur_encoding, out_encoding);
+
+ if (testbuf != NULL)
+ g_free(testbuf);
+ else
+ out_encoding = CS_UTF_8;
+
mimestr_len = strlen(MIMESEP_BEGIN) + strlen(out_encoding) +
strlen(mimesep_enc) + strlen(MIMESEP_END);