gsasl  1.10.0
About: GNU SASL is an implementation of the Simple Authentication and Security Layer (SASL). Development version.
  Fossies Dox: gsasl-1.10.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

iconv_open.c
Go to the documentation of this file.
1 /* Character set conversion.
2  Copyright (C) 2007, 2009-2021 Free Software Foundation, Inc.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 3, or (at your option)
7  any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License along
15  with this program; if not, see <https://www.gnu.org/licenses/>. */
16 
17 #include <config.h>
18 
19 /* Specification. */
20 #include <iconv.h>
21 
22 #include <errno.h>
23 #include <string.h>
24 #include "c-ctype.h"
25 #include "c-strcase.h"
26 
27 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
28 
29 /* Namespace cleanliness. */
30 #define mapping_lookup rpl_iconv_open_mapping_lookup
31 
32 /* The macro ICONV_FLAVOR is defined to one of these or undefined. */
33 
34 #define ICONV_FLAVOR_AIX "iconv_open-aix.h"
35 #define ICONV_FLAVOR_HPUX "iconv_open-hpux.h"
36 #define ICONV_FLAVOR_IRIX "iconv_open-irix.h"
37 #define ICONV_FLAVOR_OSF "iconv_open-osf.h"
38 #define ICONV_FLAVOR_SOLARIS "iconv_open-solaris.h"
39 #define ICONV_FLAVOR_ZOS "iconv_open-zos.h"
40 
41 #ifdef ICONV_FLAVOR
42 # include ICONV_FLAVOR
43 #endif
44 
45 iconv_t
46 rpl_iconv_open (const char *tocode, const char *fromcode)
47 #undef iconv_open
48 {
49  char fromcode_upper[32];
50  char tocode_upper[32];
51  char *fromcode_upper_end;
52  char *tocode_upper_end;
53 
54 #if REPLACE_ICONV_UTF
55  /* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}.
56  Do this here, before calling the real iconv_open(), because OSF/1 5.1
57  iconv() to these encoding inserts a BOM, which is wrong.
58  We do not need to handle conversion between arbitrary encodings and
59  UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step
60  conversion through UTF-8.
61  The _ICONV_* constants are chosen to be disjoint from any iconv_t
62  returned by the system's iconv_open() functions. Recall that iconv_t
63  is a scalar type. */
64  if (c_toupper (fromcode[0]) == 'U'
65  && c_toupper (fromcode[1]) == 'T'
66  && c_toupper (fromcode[2]) == 'F'
67  && fromcode[3] == '-')
68  {
69  if (c_toupper (tocode[0]) == 'U'
70  && c_toupper (tocode[1]) == 'T'
71  && c_toupper (tocode[2]) == 'F'
72  && tocode[3] == '-')
73  {
74  if (strcmp (fromcode + 4, "8") == 0)
75  {
76  if (c_strcasecmp (tocode + 4, "16BE") == 0)
77  return _ICONV_UTF8_UTF16BE;
78  if (c_strcasecmp (tocode + 4, "16LE") == 0)
79  return _ICONV_UTF8_UTF16LE;
80  if (c_strcasecmp (tocode + 4, "32BE") == 0)
81  return _ICONV_UTF8_UTF32BE;
82  if (c_strcasecmp (tocode + 4, "32LE") == 0)
83  return _ICONV_UTF8_UTF32LE;
84  }
85  else if (strcmp (tocode + 4, "8") == 0)
86  {
87  if (c_strcasecmp (fromcode + 4, "16BE") == 0)
88  return _ICONV_UTF16BE_UTF8;
89  if (c_strcasecmp (fromcode + 4, "16LE") == 0)
90  return _ICONV_UTF16LE_UTF8;
91  if (c_strcasecmp (fromcode + 4, "32BE") == 0)
92  return _ICONV_UTF32BE_UTF8;
93  if (c_strcasecmp (fromcode + 4, "32LE") == 0)
94  return _ICONV_UTF32LE_UTF8;
95  }
96  }
97  }
98 #endif
99 
100  /* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1
101  here. This would lead to programs that work in some locales (such as the
102  "C" or "en_US" locales) but do not work in East Asian locales. It is
103  better if programmers make their programs depend on GNU libiconv (except
104  on glibc systems), e.g. by using the AM_ICONV macro and documenting the
105  dependency in an INSTALL or DEPENDENCIES file. */
106 
107  /* Try with the original names first.
108  This covers the case when fromcode or tocode is a lowercase encoding name
109  that is understood by the system's iconv_open but not listed in our
110  mappings table. */
111  {
112  iconv_t cd = iconv_open (tocode, fromcode);
113  if (cd != (iconv_t)(-1))
114  return cd;
115  }
116 
117  /* Convert the encodings to upper case, because
118  1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case
119  matters,
120  2. it makes searching in the table faster. */
121  {
122  const char *p = fromcode;
123  char *q = fromcode_upper;
124  while ((*q = c_toupper (*p)) != '\0')
125  {
126  p++;
127  q++;
128  if (q == &fromcode_upper[SIZEOF (fromcode_upper)])
129  {
130  errno = EINVAL;
131  return (iconv_t)(-1);
132  }
133  }
134  fromcode_upper_end = q;
135  }
136 
137  {
138  const char *p = tocode;
139  char *q = tocode_upper;
140  while ((*q = c_toupper (*p)) != '\0')
141  {
142  p++;
143  q++;
144  if (q == &tocode_upper[SIZEOF (tocode_upper)])
145  {
146  errno = EINVAL;
147  return (iconv_t)(-1);
148  }
149  }
150  tocode_upper_end = q;
151  }
152 
153 #ifdef ICONV_FLAVOR
154  /* Apply the mappings. */
155  {
156  const struct mapping *m =
157  mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper);
158 
159  fromcode = (m != NULL ? m->vendor_name : fromcode_upper);
160  }
161  {
162  const struct mapping *m =
163  mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper);
164 
165  tocode = (m != NULL ? m->vendor_name : tocode_upper);
166  }
167 #else
168  fromcode = fromcode_upper;
169  tocode = tocode_upper;
170 #endif
171 
172  return iconv_open (tocode, fromcode);
173 }
int c_strcasecmp(const char *s1, const char *s2) _GL_ATTRIBUTE_PURE
Definition: c-strcasecmp.c:27
_GL_INLINE int c_toupper(int c)
Definition: c-ctype.h:349
#define NULL
Definition: stddef.in.h:72
iconv_t rpl_iconv_open(const char *tocode, const char *fromcode)
Definition: iconv_open.c:46
#define SIZEOF(a)
Definition: iconv_open.c:27
#define mapping_lookup
Definition: iconv_open.c:30
size_t m
Definition: mbrtowc-impl.h:43
const char * p
Definition: mbrtowc-impl.h:42