2 * Copyright (C) 1999-2001 Free Software Foundation, Inc.
3 * This file is part of the GNU LIBICONV Library.
5 * The GNU LIBICONV Library is free software; you can redistribute it
6 * and/or modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * The GNU LIBICONV Library is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
17 * If not, write to the Free Software Foundation, Inc., 59 Temple Place -
18 * Suite 330, Boston, MA 02111-1307, USA.
26 #include "libcharset.h"
29 * Consider those system dependent encodings that are needed for the
43 * Data type for general conversion loop.
46 size_t (*loop_convert
) (iconv_t icd
,
47 const char* * inbuf
, size_t *inbytesleft
,
48 char* * outbuf
, size_t *outbytesleft
);
49 size_t (*loop_reset
) (iconv_t icd
,
50 char* * outbuf
, size_t *outbytesleft
);
56 #include "converters.h"
59 * Transliteration tables.
61 #include "cjk_variants.h"
65 * Table of all supported encodings.
68 struct mbtowc_funcs ifuncs
; /* conversion multibyte -> unicode */
69 struct wctomb_funcs ofuncs
; /* conversion unicode -> multibyte */
70 int oflags
; /* flags for unicode -> multibyte conversion */
73 #define DEFENCODING(xxx_names,xxx,xxx_ifuncs,xxx_ofuncs1,xxx_ofuncs2) \
75 #include "encodings.def"
77 #include "encodings_aix.def"
80 #include "encodings_osf1.def"
83 #include "encodings_dos.def"
85 #include "encodings_local.def"
87 ei_for_broken_compilers_that_dont_like_trailing_commas
90 static struct encoding
const all_encodings
[] = {
91 #define DEFENCODING(xxx_names,xxx,xxx_ifuncs,xxx_ofuncs1,xxx_ofuncs2) \
92 { xxx_ifuncs, xxx_ofuncs1,xxx_ofuncs2, ei_##xxx##_oflags },
93 #include "encodings.def"
95 #include "encodings_aix.def"
98 #include "encodings_osf1.def"
101 #include "encodings_dos.def"
104 #define DEFENCODING(xxx_names,xxx,xxx_ifuncs,xxx_ofuncs1,xxx_ofuncs2) \
105 { xxx_ifuncs, xxx_ofuncs1,xxx_ofuncs2, 0 },
106 #include "encodings_local.def"
116 * Alias lookup function.
118 * struct alias { const char* name; unsigned int encoding_index; };
119 * const struct alias * aliases_lookup (const char *str, unsigned int len);
120 * #define MAX_WORD_LENGTH ...
125 * System dependent alias lookup function.
127 * const struct alias * aliases2_lookup (const char *str);
129 #if defined(USE_AIX) || defined(USE_OSF1) || defined(USE_DOS) /* || ... */
130 static struct alias sysdep_aliases
[] = {
132 #include "aliases_aix.h"
135 #include "aliases_osf1.h"
138 #include "aliases_dos.h"
145 aliases2_lookup (register const char *str
)
149 for (ptr
= sysdep_aliases
, count
= sizeof(sysdep_aliases
)/sizeof(sysdep_aliases
[0]); count
> 0; ptr
++, count
--)
150 if (!strcmp(str
,ptr
->name
))
155 #define aliases2_lookup(str) NULL
159 /* Like !strcasecmp, except that the both strings can be assumed to be ASCII
160 and the first string can be assumed to be in uppercase. */
161 static int strequal (const char* str1
, const char* str2
)
166 c1
= * (unsigned char *) str1
++;
167 c2
= * (unsigned char *) str2
++;
170 if (c2
>= 'a' && c2
<= 'z')
179 iconv_t
iconv_open (const char* tocode
, const char* fromcode
)
181 struct conv_struct
* cd
;
182 char buf
[MAX_WORD_LENGTH
+10+1];
185 const struct alias
* ap
;
187 unsigned int from_index
;
189 unsigned int to_index
;
191 int transliterate
= 0;
193 /* Before calling aliases_lookup, convert the input string to upper case,
194 * and check whether it's entirely ASCII (we call gperf with option "-7"
195 * to achieve a smaller table) and non-empty. If it's not entirely ASCII,
196 * or if it's too long, it is not a valid encoding name.
198 for (to_wchar
= 0;;) {
199 /* Search tocode in the table. */
200 for (cp
= tocode
, bp
= buf
, count
= MAX_WORD_LENGTH
+10+1; ; cp
++, bp
++) {
201 unsigned char c
= * (unsigned char *) cp
;
204 if (c
>= 'a' && c
<= 'z')
212 if (bp
-buf
> 10 && memcmp(bp
-10,"//TRANSLIT",10)==0) {
217 ap
= aliases_lookup(buf
,bp
-buf
);
219 ap
= aliases2_lookup(buf
);
223 if (ap
->encoding_index
== ei_local_char
) {
224 tocode
= locale_charset();
227 if (ap
->encoding_index
== ei_local_wchar_t
) {
228 #if __STDC_ISO_10646__
229 if (sizeof(wchar_t) == 4) {
230 to_index
= ei_ucs4internal
;
233 if (sizeof(wchar_t) == 2) {
234 to_index
= ei_ucs2internal
;
237 if (sizeof(wchar_t) == 1) {
238 to_index
= ei_iso8859_1
;
244 tocode
= locale_charset();
249 to_index
= ap
->encoding_index
;
252 for (from_wchar
= 0;;) {
253 /* Search fromcode in the table. */
254 for (cp
= fromcode
, bp
= buf
, count
= MAX_WORD_LENGTH
+10+1; ; cp
++, bp
++) {
255 unsigned char c
= * (unsigned char *) cp
;
258 if (c
>= 'a' && c
<= 'z')
266 if (bp
-buf
> 10 && memcmp(bp
-10,"//TRANSLIT",10)==0) {
270 ap
= aliases_lookup(buf
,bp
-buf
);
272 ap
= aliases2_lookup(buf
);
276 if (ap
->encoding_index
== ei_local_char
) {
277 fromcode
= locale_charset();
280 if (ap
->encoding_index
== ei_local_wchar_t
) {
281 #if __STDC_ISO_10646__
282 if (sizeof(wchar_t) == 4) {
283 from_index
= ei_ucs4internal
;
286 if (sizeof(wchar_t) == 2) {
287 from_index
= ei_ucs2internal
;
290 if (sizeof(wchar_t) == 1) {
291 from_index
= ei_iso8859_1
;
297 fromcode
= locale_charset();
302 from_index
= ap
->encoding_index
;
305 cd
= (struct conv_struct
*) malloc(from_wchar
!= to_wchar
306 ? sizeof(struct wchar_conv_struct
)
307 : sizeof(struct conv_struct
));
310 return (iconv_t
)(-1);
312 cd
->iindex
= from_index
;
313 cd
->ifuncs
= all_encodings
[from_index
].ifuncs
;
314 cd
->oindex
= to_index
;
315 cd
->ofuncs
= all_encodings
[to_index
].ofuncs
;
316 cd
->oflags
= all_encodings
[to_index
].oflags
;
317 /* Initialize the loop functions. */
322 cd
->lfuncs
.loop_convert
= wchar_id_loop_convert
;
323 cd
->lfuncs
.loop_reset
= wchar_id_loop_reset
;
327 cd
->lfuncs
.loop_convert
= wchar_to_loop_convert
;
328 cd
->lfuncs
.loop_reset
= wchar_to_loop_reset
;
335 cd
->lfuncs
.loop_convert
= wchar_from_loop_convert
;
336 cd
->lfuncs
.loop_reset
= wchar_from_loop_reset
;
340 cd
->lfuncs
.loop_convert
= unicode_loop_convert
;
341 cd
->lfuncs
.loop_reset
= unicode_loop_reset
;
344 /* Initialize the states. */
345 memset(&cd
->istate
,'\0',sizeof(state_t
));
346 memset(&cd
->ostate
,'\0',sizeof(state_t
));
347 /* Initialize the operation flags. */
348 cd
->transliterate
= transliterate
;
349 /* Initialize additional fields. */
350 if (from_wchar
!= to_wchar
) {
351 struct wchar_conv_struct
* wcd
= (struct wchar_conv_struct
*) cd
;
352 memset(&wcd
->state
,'\0',sizeof(mbstate_t));
358 return (iconv_t
)(-1);
361 size_t iconv (iconv_t icd
,
362 ICONV_CONST
char* * inbuf
, size_t *inbytesleft
,
363 char* * outbuf
, size_t *outbytesleft
)
365 conv_t cd
= (conv_t
) icd
;
366 if (inbuf
== NULL
|| *inbuf
== NULL
)
367 return cd
->lfuncs
.loop_reset(icd
,outbuf
,outbytesleft
);
369 return cd
->lfuncs
.loop_convert(icd
,
370 (const char* *)inbuf
,inbytesleft
,
371 outbuf
,outbytesleft
);
374 int iconv_close (iconv_t icd
)
376 conv_t cd
= (conv_t
) icd
;
381 #ifndef LIBICONV_PLUG
383 int iconvctl (iconv_t icd
, int request
, void* argument
)
385 conv_t cd
= (conv_t
) icd
;
389 ((cd
->lfuncs
.loop_convert
== unicode_loop_convert
390 && cd
->iindex
== cd
->oindex
)
391 || cd
->lfuncs
.loop_convert
== wchar_id_loop_convert
394 case ICONV_GET_TRANSLITERATE
:
395 *(int *)argument
= cd
->transliterate
;
397 case ICONV_SET_TRANSLITERATE
:
398 cd
->transliterate
= (*(const int *)argument
? 1 : 0);
406 int _libiconv_version
= _LIBICONV_VERSION
;