4 * ROX-Filer, filer for the ROX desktop project
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
18 * Place, Suite 330, Boston, MA 02111-1307 USA
21 /* This code is taken from glib2 and has been converted to the GPL, as allowed
22 * under the terms of the LGPL. Removed lots of stuff! When we move fully to
23 * glib2, this file will disappear.
25 * gconvert.c: Convert between character sets using iconv
26 * Copyright Red Hat Inc., 2000
27 * Authors: Havoc Pennington <hp@redhat.com>, Owen Taylor <otaylor@redhat.com
53 g_utf8_get_charset_internal (const char **a
)
55 const char *charset
= getenv("CHARSET");
58 if (charset
&& *charset
)
62 if (charset
&& strstr (charset
, "UTF-8"))
68 /* Try to find a sensible default... */
70 cd
= iconv_open (*a
, "UTF-8");
71 if (cd
== (iconv_t
) -1)
74 cd
= (GIConv
) iconv_open (*a
, "UTF-8");
76 if (cd
== (iconv_t
) -1)
84 static int utf8_locale_cache
= -1;
85 static const char *utf8_charset_cache
= NULL
;
90 g_get_charset (const char **charset
)
93 if (utf8_locale_cache
!= -1)
96 *charset
= utf8_charset_cache
;
97 return utf8_locale_cache
;
99 utf8_locale_cache
= g_utf8_get_charset_internal (&utf8_charset_cache
);
101 *charset
= utf8_charset_cache
;
102 return utf8_locale_cache
;
111 g_iconv (GIConv converter
,
115 gsize
*outbytes_left
)
117 iconv_t cd
= (iconv_t
)converter
;
119 return iconv (cd
, inbuf
, inbytes_left
, outbuf
, outbytes_left
);
123 g_iconv_close (GIConv converter
)
125 iconv_t cd
= (iconv_t
)converter
;
127 return iconv_close (cd
);
131 open_converter (const gchar
*to_codeset
,
132 const gchar
*from_codeset
,
135 GIConv cd
= (GIConv
) iconv_open (to_codeset
, from_codeset
);
137 if (cd
== (iconv_t
) -1)
139 /* Something went wrong. */
141 g_warning("Conversion from character set '%s' to '%s' is not supported",
142 from_codeset
, to_codeset
);
144 g_warning("Could not open converter from '%s' to '%s': %s",
145 from_codeset
, to_codeset
, strerror (errno
));
154 g_convert (const gchar
*str
,
156 const gchar
*to_codeset
,
157 const gchar
*from_codeset
,
159 gsize
*bytes_written
,
166 g_return_val_if_fail (str
!= NULL
, NULL
);
167 g_return_val_if_fail (to_codeset
!= NULL
, NULL
);
168 g_return_val_if_fail (from_codeset
!= NULL
, NULL
);
170 cd
= open_converter (to_codeset
, from_codeset
, error
);
172 if (cd
== (GIConv
) -1)
183 res
= g_convert_with_iconv (str
, len
, cd
,
184 bytes_read
, bytes_written
,
197 g_convert_with_iconv (const gchar
*str
,
201 gsize
*bytes_written
,
207 gsize inbytes_remaining
;
208 gsize outbytes_remaining
;
211 gboolean have_error
= FALSE
;
213 g_return_val_if_fail (str
!= NULL
, NULL
);
214 g_return_val_if_fail (converter
!= (GIConv
) -1, NULL
);
220 inbytes_remaining
= len
;
221 outbuf_size
= len
+ 1; /* + 1 for nul in case len == 1 */
223 outbytes_remaining
= outbuf_size
- 1; /* -1 for nul */
224 outp
= dest
= g_malloc (outbuf_size
);
228 err
= g_iconv (converter
, (char **)&p
, &inbytes_remaining
, &outp
, &outbytes_remaining
);
230 if (err
== (size_t) -1)
235 /* Incomplete text, do not report an error */
239 size_t used
= outp
- dest
;
242 dest
= g_realloc (dest
, outbuf_size
);
245 outbytes_remaining
= outbuf_size
- used
- 1; /* -1 for nul */
250 g_warning("Invalid byte sequence in conversion input");
254 g_warning("Error during conversion: %s", strerror (errno
));
263 *bytes_read
= p
- str
;
266 if ((p
- str
) != len
)
270 g_warning("Partial character sequence at end of input");
277 *bytes_written
= outp
- dest
; /* Doesn't include '\0' */
290 g_locale_to_utf8 (const gchar
*opsysstring
,
293 gsize
*bytes_written
,
298 if (g_get_charset (&charset
))
299 return g_strdup (opsysstring
);
301 return g_convert (opsysstring
, len
,
302 "UTF-8", charset
, bytes_read
, bytes_written
, error
);
306 g_locale_from_utf8 (const gchar
*utf8string
,
309 gsize
*bytes_written
,
312 const gchar
*charset
;
314 if (g_get_charset (&charset
))
315 return g_strdup (utf8string
);
317 return g_convert (utf8string
, len
,
318 charset
, "UTF-8", bytes_read
, bytes_written
, error
);