gaim/gaim
Clone
Summary
Browse
Changes
Graph
a nice patch from A Lee for i18n approved by paco-paco
gtk1-stable
2002-09-27, Luke Schierer
015792ac3198
Parents
96a97bfdc580
Children
1a43b7b199d2
a nice patch from A Lee for i18n approved by paco-paco
1 files changed, 70 insertions(+), 32 deletions(-)
+70
-32
src/util.c
--- a/src/util.c Thu Sep 26 17:48:24 2002 -0400
+++ b/src/util.c Fri Sep 27 22:58:53 2002 -0400
@@ -1121,48 +1121,86 @@
fclose(fd);
}
-char *convert_string(char *str, const char *destset, const char *srcset)
+char *convert_string(const char *in, const char *destset, const char *srcset)
{
#ifdef HAVE_ICONV
- char *buf;
- iconv_t cd;
- size_t insize = 0;
- size_t outsize = 0;
- size_t nconv = 0;
- char *inptr;
- char *outptr;
- char *ret;
+ int n = 0, i = 0;
+ int inlen;
+ char *result;
+ iconv_t cd1, cd2; /* cd1: srcset->UCS-4, cd2: UCS-4->destset */
+ size_t outleft, ucs4_outleft;
+ size_t old_inlen, old_outleft;
+ size_t tmp;
+ char *result_ptr;
+ char *ucs4_result;
+ char *ucs4_result_ptr;
- if (!str)
- return NULL;
- buf = g_malloc(strlen(str)*4);
- insize = strlen(str);
- inptr = str;
- outsize = strlen(str)*4;
- outptr = buf;
+ if (!in)
+ return NULL;
+
+ cd1 = iconv_open("UCS-4", srcset);
+ cd2 = iconv_open(destset, "UCS-4");
- cd = iconv_open(destset, srcset);
- if (cd == (iconv_t) -1) {
- g_free(buf);
+ if (cd1 == (iconv_t) -1 || cd2 == (iconv_t) -1) {
+ if ( cd1 != (iconv_t)-1 ) {
+ iconv_close(cd1);
+ }
+ else if ( cd2 != (iconv_t)-1 ) {
+ iconv_close(cd2);
+ }
debug_printf("iconv_open(%s, %s) Error\n",destset, srcset);
- return g_strdup(str);
+ return g_strdup(in);
}
- nconv = iconv(cd, &inptr, &insize, &outptr, &outsize);
- if (nconv == (size_t) -1) {
- debug_printf("iconv Error\n");
- g_free(buf);
- return g_strdup(str);
+ /* use iconv to convert srcset to destset */
+ /* we will convert srcset to UCS-4 and convert it again to destset
+ one character by one because iconv doesn't convert whole string
+ when it encountered a character which doesn't exist in the
+ target encoding charset. */
+
+ inlen = strlen(in);
+ if ( inlen <= 0 ) { /* no need to process an empty string. */
+ result = g_malloc(1);
+ result[0] = '\0';
+ return result;
}
- *outptr = '\0';
- iconv_close(cd);
+ outleft = inlen * 6; /* in maximum, one character will occupy 6 bytes in srcset */
+ result = g_malloc(outleft + 1);
+ ucs4_outleft = inlen * 4;
+ ucs4_result = g_malloc(ucs4_outleft); /* ucs4 conversion buffer */
+
+ result_ptr = ucs4_result;
+ tmp = ucs4_outleft;
+ iconv(cd1, &in, &inlen, &result_ptr, &ucs4_outleft);
+ n = (tmp - ucs4_outleft) / 4; /* 'n' will indicate the number of chars */
+ debug_printf("ucs4_bytes: %d", (tmp-ucs4_outleft));
- ret = g_strdup(buf);
- g_free(buf);
-
- return ret;
+ result_ptr = result;
+ ucs4_result_ptr = ucs4_result;
+ tmp = outleft; /* remember last buffer remainder */
+ for ( i = 0; i < n; i ++ ) {
+ inlen = 4;
+ iconv(cd2, &ucs4_result_ptr, &inlen, &result_ptr, &outleft);
+ if ( tmp == outleft ) {
+ /* if nothing has ben converted, add '?' symbol */
+ *(result_ptr++) = '?';
+ outleft --;
+ ucs4_result_ptr += 4;
+ }
+
+ tmp = outleft; /* remember last buffer remainder */
+ }
+
+ iconv_close(cd2);
+ iconv_close(cd1);
+
+ *result_ptr = '\0';
+
+ g_free(ucs4_result);
+
+ return result;
#else
- return g_strdup(str);
+ return g_strdup(in);
#endif
}