Mercurial > pt1.oyama
comparison src/util_iconv.c @ 125:e413158cae13
Add ushare project files.
author | naoyan@johnstown.minaminoshima.org |
---|---|
date | Sun, 03 Oct 2010 11:35:19 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
124:9c7bc6c0327e | 125:e413158cae13 |
---|---|
1 /* | |
2 * util_iconv.c : GeeXboX uShare iconv string encoding utlities. | |
3 * Originally developped for the GeeXboX project. | |
4 * Copyright (C) 2005-2007 Alexis Saettler <asbin@asbin.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 Library General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License along | |
17 * with this program; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 */ | |
20 | |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <string.h> | |
24 #include <errno.h> | |
25 | |
26 #include "util_iconv.h" | |
27 | |
28 #if HAVE_ICONV | |
29 #include <iconv.h> | |
30 static iconv_t cd = 0; | |
31 #endif | |
32 | |
33 #if HAVE_LANGINFO_CODESET | |
34 #include <langinfo.h> | |
35 #endif | |
36 | |
37 void | |
38 setup_iconv (void) | |
39 { | |
40 #if HAVE_ICONV && HAVE_LANGINFO_CODESET | |
41 char *mycodeset = NULL; | |
42 | |
43 mycodeset = nl_langinfo (CODESET); | |
44 if (!mycodeset) | |
45 return; | |
46 | |
47 /** | |
48 * Setup conversion descriptor if user's console is non-UTF-8. Otherwise | |
49 * we can just leave cd as NULL | |
50 */ | |
51 if (strcmp (mycodeset, UTF8)) | |
52 { | |
53 cd = iconv_open (UTF8, mycodeset); | |
54 if (cd == (iconv_t) (-1)) | |
55 { | |
56 perror ("iconv_open"); | |
57 cd = 0; | |
58 } | |
59 } | |
60 #endif | |
61 } | |
62 | |
63 void | |
64 finish_iconv (void) | |
65 { | |
66 #if HAVE_ICONV | |
67 if (!cd) | |
68 return; | |
69 if (iconv_close (cd) < 0) | |
70 perror ("iconv_close"); | |
71 cd = 0; | |
72 #endif | |
73 } | |
74 | |
75 /** | |
76 * iconv_convert : convert a string, using the current codeset | |
77 * return: a malloc'd string with the converted result | |
78 */ | |
79 char * | |
80 iconv_convert (const char *input) | |
81 { | |
82 #if HAVE_ICONV | |
83 size_t inputsize = strlen (input) + 1; | |
84 size_t dummy = 0; | |
85 size_t length = 0; | |
86 char *result; | |
87 char *inptr, *outptr; | |
88 size_t insize, outsize; | |
89 | |
90 /* conversion not necessary. save our time. */ | |
91 if (!cd) | |
92 return strdup (input); | |
93 | |
94 /* Determine the length we need. */ | |
95 iconv (cd, NULL, NULL, NULL, &dummy); | |
96 { | |
97 static char tmpbuf[BUFSIZ]; | |
98 inptr = (char*) input; | |
99 insize = inputsize; | |
100 while (insize > 0) | |
101 { | |
102 outptr = tmpbuf; | |
103 outsize = BUFSIZ; | |
104 if (iconv (cd, &inptr, &insize, &outptr, &outsize) == (size_t) (-1)) | |
105 { | |
106 /** | |
107 * if error is EINVAL or EILSEQ, conversion must be stoped, | |
108 * but if it is E2BIG (not enough space in buffer), we just loop again | |
109 */ | |
110 if( errno != E2BIG) | |
111 { | |
112 perror ("error iconv"); | |
113 return NULL; | |
114 } | |
115 } | |
116 length += outptr - tmpbuf; | |
117 } | |
118 | |
119 outptr = tmpbuf; | |
120 outsize = BUFSIZ; | |
121 if (iconv (cd, NULL, NULL, &outptr, &outsize) == (size_t) (-1)) | |
122 { | |
123 perror ("error iconv"); | |
124 return NULL; | |
125 } | |
126 length += outptr - tmpbuf; | |
127 } | |
128 | |
129 /* length determined, allocate result space */ | |
130 if ((result = (char*) malloc (length * sizeof (char))) == NULL) | |
131 { | |
132 perror ("error malloc"); | |
133 return NULL; | |
134 } | |
135 | |
136 /* Do the conversion for real. */ | |
137 iconv (cd, NULL, NULL, NULL, &dummy); | |
138 { | |
139 inptr = (char*) input; | |
140 insize = inputsize; | |
141 outptr = result; | |
142 outsize = length; | |
143 while (insize > 0) | |
144 { | |
145 if (iconv (cd, &inptr, &insize, &outptr, &outsize) == (size_t) (-1)) | |
146 { | |
147 if (errno != E2BIG) | |
148 { | |
149 perror ("error iconv"); | |
150 free (result); | |
151 return NULL; | |
152 } | |
153 } | |
154 } | |
155 if (iconv (cd, NULL, NULL, &outptr, &outsize) == (size_t) (-1)) | |
156 { | |
157 perror ("error iconv"); | |
158 free (result); | |
159 return NULL; | |
160 } | |
161 | |
162 if (outsize != 0) | |
163 abort (); | |
164 } | |
165 | |
166 return result; | |
167 #else | |
168 return strdup (input); | |
169 #endif | |
170 } |