comparison lib/charset-conv.c @ 950:c7d7a081cd9c

2008-03-04 Brian Masney <masneyb@gftp.org> * lib/gftp.h lib/socket-connect.c lib/sockutils.c lib/protocols.c lib/Makefile.am lib/charset-conv.c lib/parse-dir-listing.c - split protocols.c into smaller files. No changes were made to the moved functions.
author masneyb
date Tue, 04 Mar 2008 12:28:40 +0000
parents
children 63555c9744c2
comparison
equal deleted inserted replaced
949:9a6571938f89 950:c7d7a081cd9c
1 /*****************************************************************************/
2 /* charset-conv.c - contains functions for performing conversions between */
3 /* character sets. */
4 /* Copyright (C) 1998-2008 Brian Masney <masneyb@gftp.org> */
5 /* */
6 /* This program is free software; you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation; either version 2 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* This program is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with this program; if not, write to the Free Software */
18 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */
19 /*****************************************************************************/
20
21 #include "gftp.h"
22 static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $";
23
24 #if GLIB_MAJOR_VERSION > 1
25
26 static /*@null@*/ char *
27 _gftp_get_next_charset (char **curpos)
28 {
29 char *ret, *endpos;
30 size_t len, retlen;
31
32 if (**curpos == '\0')
33 return (NULL);
34
35 for (; **curpos == ' ' || **curpos == '\t'; (*curpos)++);
36
37 if ((endpos = strchr (*curpos, ',')) == NULL)
38 len = strlen (*curpos) - 1; /* the trailing ',' should be omitted */
39 else
40 len = endpos - *curpos;
41
42 for (retlen = len - 1;
43 (*curpos)[retlen - 1] == ' ' || (*curpos)[retlen - 1] == '\t';
44 retlen--);
45
46 retlen++; /* Needed due to the len - 1 above... */
47 ret = g_malloc0 (retlen + 1);
48 memcpy (ret, *curpos, retlen);
49
50 for (*curpos += len; **curpos == ','; (*curpos)++);
51
52 return (ret);
53 }
54
55
56 static void
57 _do_show_iconv_error (const char *str, char *charset, int from_utf8,
58 GError * error)
59 {
60 const char *fromset, *toset;
61
62 if (from_utf8)
63 {
64 fromset = "UTF-8";
65 toset = charset;
66 }
67 else
68 {
69 fromset = charset;
70 toset = "UTF-8";
71 }
72
73 printf (_("Error converting string '%s' from character set %s to character set %s: %s\n"),
74 str, fromset, toset, error->message);
75 }
76
77
78 /*@null@*/ static char *
79 _do_convert_string (gftp_request * request, int is_filename, int force_local,
80 const char *str, size_t *dest_len, int from_utf8)
81 {
82 char *remote_charsets, *ret, *fromset, *toset, *stpos, *cur_charset;
83 GError * error;
84 gsize bread;
85
86 if (request == NULL)
87 return (NULL);
88
89 if (g_utf8_validate (str, -1, NULL) != from_utf8)
90 return (NULL);
91
92 error = NULL;
93 gftp_lookup_request_option (request, "remote_charsets", &remote_charsets);
94 if (*remote_charsets == '\0' || request->use_local_encoding ||
95 force_local == 1)
96 {
97 if (from_utf8)
98 {
99 if (is_filename)
100 ret = g_filename_from_utf8 (str, -1, &bread, dest_len, &error);
101 else
102 ret = g_locale_from_utf8 (str, -1, &bread, dest_len, &error);
103 }
104 else
105 {
106 if (is_filename)
107 ret = g_filename_to_utf8 (str, -1, &bread, dest_len, &error);
108 else
109 ret = g_locale_to_utf8 (str, -1, &bread, dest_len, &error);
110 }
111
112 if (ret == NULL)
113 _do_show_iconv_error (str, request->iconv_charset, from_utf8, error);
114
115 return (ret);
116 }
117
118 if (from_utf8)
119 {
120 if (request->iconv_from_initialized)
121 {
122 ret = g_convert_with_iconv (str, -1, request->iconv_from, &bread, dest_len,
123 &error);
124 if (ret == NULL)
125 _do_show_iconv_error (str, request->iconv_charset, from_utf8, error);
126
127 return (ret);
128 }
129 }
130 else
131 {
132 if (request->iconv_to_initialized)
133 {
134 ret = g_convert_with_iconv (str, -1, request->iconv_to, &bread, dest_len,
135 &error);
136 if (ret == NULL)
137 _do_show_iconv_error (str, request->iconv_charset, from_utf8, error);
138
139 return (ret);
140 }
141 }
142
143 stpos = remote_charsets;
144 while ((cur_charset = _gftp_get_next_charset (&stpos)) != NULL)
145 {
146 if (from_utf8)
147 {
148 fromset = "UTF-8";
149 toset = cur_charset;
150 if ((request->iconv_from = g_iconv_open (toset, fromset)) == (GIConv) -1)
151 {
152 g_free (cur_charset);
153 continue;
154 }
155
156 error = NULL;
157 if ((ret = g_convert_with_iconv (str, -1, request->iconv_from, &bread,
158 dest_len, &error)) == NULL)
159 {
160 g_iconv_close (request->iconv_from);
161 request->iconv_from = NULL;
162 _do_show_iconv_error (str, cur_charset, from_utf8, error);
163 g_free (cur_charset);
164 continue;
165 }
166
167 request->iconv_from_initialized = 1;
168 }
169 else
170 {
171 fromset = cur_charset;
172 toset = "UTF-8";
173 if ((request->iconv_to = g_iconv_open (toset, fromset)) == (GIConv) -1)
174 {
175 g_free (cur_charset);
176 continue;
177 }
178
179 error = NULL;
180 if ((ret = g_convert_with_iconv (str, -1, request->iconv_to, &bread,
181 dest_len, &error)) == NULL)
182 {
183 g_iconv_close (request->iconv_to);
184 request->iconv_to = NULL;
185 _do_show_iconv_error (str, cur_charset, from_utf8, error);
186 g_free (cur_charset);
187 continue;
188 }
189
190 request->iconv_to_initialized = 1;
191 }
192
193 request->iconv_charset = cur_charset;
194 return (ret);
195 }
196
197 return (NULL);
198 }
199
200 char *
201 gftp_string_to_utf8 (gftp_request * request, const char *str, size_t *dest_len)
202 {
203 return (_do_convert_string (request, 0, 0, str, dest_len, 0));
204 }
205
206
207 char *
208 gftp_string_from_utf8 (gftp_request * request, int force_local, const char *str,
209 size_t *dest_len)
210 {
211 return (_do_convert_string (request, 0, force_local, str, dest_len, 1));
212 }
213
214
215 char *
216 gftp_filename_to_utf8 (gftp_request * request, const char *str,
217 size_t *dest_len)
218 {
219 return (_do_convert_string (request, 1, 0, str, dest_len, 0));
220 }
221
222
223 char *
224 gftp_filename_from_utf8 (gftp_request * request, const char *str,
225 size_t *dest_len)
226 {
227 return (_do_convert_string (request, 1, 0, str, dest_len, 1));
228 }
229
230 #else
231
232 char *
233 gftp_string_to_utf8 (gftp_request * request, const char *str, size_t dest_len)
234 {
235 return (NULL);
236 }
237
238
239 char *
240 gftp_string_from_utf8 (gftp_request * request, int force_local, const char *str,
241 size_t dest_len)
242 {
243 return (NULL);
244 }
245
246
247 char *
248 gftp_filename_to_utf8 (gftp_request * request, const char *str, size_t dest_len)
249 {
250 return (NULL);
251 }
252
253
254 char *
255 gftp_filename_from_utf8 (gftp_request * request, int force_local,
256 const char *str, size_t dest_len)
257 {
258 return (NULL);
259 }
260
261 #endif
262
263