source: trunk/libs/newlib/src/newlib/libc/iconv/lib/iconvnls.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 10.1 KB
Line 
1/*
2 * Copyright (c) 2003-2004, Artem B. Bityuckiy
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25#include <_ansi.h>
26#include <reent.h>
27#include <newlib.h>
28#include <sys/types.h>
29#include <string.h>
30#include <stdlib.h>
31#include <sys/iconvnls.h>
32#ifdef _MB_CAPABLE
33#include <wchar.h>
34#include <iconv.h>
35#include <string.h>
36#include <stdlib.h>
37#include <errno.h>
38#include "local.h"
39#include "conv.h"
40#include "ucsconv.h"
41#include "iconvnls.h"
42#endif
43
44/*
45 * _iconv_nls_construct_filename -- constructs full file name.
46 *
47 * PARAMETERS:
48 *   struct _reent *rptr - reent structure of current thread/process. 
49 *   const char *file   - the name of file.
50 *   const char *dir    - the name of subdirectory;
51 *   const char *ext    - file extension.
52 *
53 * DESCRIPTION:
54 *   Function constructs patch to icionv-related file.
55 *   'file' shouldn't be NULL. Doesn't use extension if 'ext' is NULL.
56 *
57 * RETURN:
58 *   The pointer to file name if success, In case of error returns NULL
59 *   and sets current thread's/process's errno.
60 */
61const char *
62_iconv_nls_construct_filename (struct _reent *rptr,
63                                      const char *file,
64                                      const char *dir,
65                                      const char *ext)
66{
67  int len1, len2, len3;
68  char *path;
69  char *p;
70  int dirlen = strlen (dir);
71   
72  if ((path = _getenv_r (rptr, NLS_ENVVAR_NAME)) == NULL || *path == '\0')
73    path = ICONV_DEFAULT_NLSPATH;
74
75  len1 = strlen (path);
76  len2 = strlen (file);
77  len3 = strlen (ext);
78
79  if ((p = _malloc_r (rptr, len1 + dirlen + len2 + len3 + 3)) == NULL)
80    return (const char *)NULL;
81
82  memcpy (p, path, len1);
83  if (p[len1 - 1] != '/')
84    p[len1++] = '/';
85  memcpy (p + len1, dir, dirlen);
86  len1 += dirlen;
87  p[len1++] = '/';
88  memcpy (p + len1, file, len2);
89  len1 += len2;
90  if (ext != NULL)
91  {
92    memcpy (p + len1, ext, len3);
93    len1 += len3;
94  }
95  p[len1] = '\0';
96 
97  return (const char *)p;
98}
99
100
101#ifdef _MB_CAPABLE
102/*
103 * _iconv_nls_get_mb_cur_max -- return encoding's maximum length
104 *                              of a multi-byte character.
105 *
106 * PARAMETERS:
107 *    iconv_t cd - opened iconv conversion descriptor;
108 *    int direction - "from encoding" or "to encoding" direction.
109 *
110 * DESCRIPTION:
111 *    Return maximum  length  of a multi-byte character in one of 'cd's
112 *    encoding. Return "from" encoding's value if 'direction' is 0 and
113 *    "to" encoding's value if 'direction' isn't 0.
114 */
115int
116_iconv_nls_get_mb_cur_max (iconv_t cd,
117                                  int direction)
118{
119  iconv_conversion_t *ic = (iconv_conversion_t *)cd;
120 
121  return ic->handlers->get_mb_cur_max (ic->data, direction);
122}
123
124/*
125 * _iconv_nls_is_stateful -- is encoding stateful?
126 *
127 * PARAMETERS:
128 *    iconv_t cd - opened iconv conversion descriptor;
129 *    int direction - "from encoding" or "to encoding" direction.
130 *
131 * DESCRIPTION:
132 *    Returns 0 if encoding is stateless or 1 if stateful.
133 *    Tests "from" encoding if 'direction' is 0 and
134 *    "to" encoding's value if 'direction' isn't 0.
135
136 */
137int
138_iconv_nls_is_stateful (iconv_t cd,
139                               int direction)
140{
141  iconv_conversion_t *ic = (iconv_conversion_t *)cd;
142 
143  return ic->handlers->is_stateful (ic->data, direction);
144}
145
146/*
147 * _iconv_nls_conv - special version of iconv for NLS.
148 *
149 * PARAMETERS:
150 *    Same as _iconv_r.
151 *
152 * DESCRIPTION:
153 *    Function behaves as _iconv_r but:
154 *    1.  Don't handle reset/return shift states queries
155 *        (like iconv does when 'inbuf' == NULL, etc);
156 *    2. Don't save result if 'outbuf' == NULL or
157 *       '*outbuf' == NULL;
158 *    3. Don't perform default conversion if there is no character
159 *       in "to" encoding that corresponds to character from "from"
160 *       encoding.
161 *
162 * RETURN:
163 *    Same as _iconv_r.
164 */
165size_t
166_iconv_nls_conv (struct _reent *rptr,
167                        iconv_t cd,
168                        const char **inbuf,
169                        size_t *inbytesleft,
170                        char **outbuf,
171                        size_t *outbytesleft)
172{
173  iconv_conversion_t *ic = (iconv_conversion_t *)cd;
174  int flags = ICONV_FAIL_BIT;
175
176  if ((void *)cd == NULL || cd == (iconv_t)-1 || ic->data == NULL
177       || (ic->handlers != &_iconv_null_conversion_handlers
178           && ic->handlers != &_iconv_ucs_conversion_handlers))
179    {
180      __errno_r (rptr) = EBADF;
181      return (size_t)-1;
182    }
183 
184  if (inbytesleft == NULL || *inbytesleft == 0)
185    return (size_t)0;
186 
187  if (outbuf == NULL || *outbuf == NULL)
188    flags |= ICONV_DONT_SAVE_BIT;
189 
190  if (outbytesleft == NULL || *outbytesleft == 0)
191    {
192      __errno_r (rptr) = E2BIG;
193      return (size_t)-1;
194    }
195
196  return ic->handlers->convert (rptr,
197                                ic->data,
198                                (const unsigned char**)inbuf,
199                                inbytesleft,
200                                (unsigned char**)outbuf,
201                                outbytesleft,
202                                flags);
203}
204
205/*
206 * _iconv_nls_get_state -- get encoding's current shift state value.
207 *
208 * PARAMETERS:
209 *    iconv_t cd - iconv descriptor;
210 *    mbstate_t *ps - where to save shift state;
211 *    int direction - "from" encoding if 0, "to" encoding if 1.
212 *
213 * DESCRIPTION:
214 *    Save encoding's current shift state to 'ps'. Save "from" encoding's
215 *    shift state if 'direction' is 0 and "to" encodings's shift state
216 *    if 'direction' isn't 0.
217 */
218void
219_iconv_nls_get_state (iconv_t cd,
220                             mbstate_t *ps,
221                             int direction)
222{
223  iconv_conversion_t *ic = (iconv_conversion_t *)cd;
224 
225  ic->handlers->get_state (ic->data, ps, direction);
226
227  return;
228}
229
230/*
231 * _iconv_nls_set_state -- set encoding's current shift state value.
232 *
233 * PARAMETERS:
234 *    iconv_t cd    - iconv descriptor;
235 *    mbstate_t *ps - where to save shift state.
236 *    int direction - "from" encoding if 0, "to" encoding if 1.
237 *
238 * DESCRIPTION:
239 *    Set encoding's current shift state.
240 *
241 * RETURN:
242 *    0 if success, -1 if failure.
243 */
244int
245_iconv_nls_set_state (iconv_t cd,
246                             mbstate_t *ps,
247                             int direction)
248{
249  iconv_conversion_t *ic = (iconv_conversion_t *)cd;
250 
251  return ic->handlers->set_state (ic->data, ps, direction);
252}
253
254/* Same as iconv_open() but don't perform name resolving */
255static iconv_t
256iconv_open1 (struct _reent *rptr,
257                     const char *to,
258                     const char *from)
259{
260  iconv_conversion_t *ic;
261   
262  if (to == NULL || from == NULL || *to == '\0' || *from == '\0')
263    return (iconv_t)-1;
264
265  ic = (iconv_conversion_t *)_malloc_r (rptr, sizeof (iconv_conversion_t));
266  if (ic == NULL)
267    return (iconv_t)-1;
268
269  /* Select which conversion type to use */
270  if (strcmp (from, to) == 0)
271    {
272      /* Use null conversion */
273      ic->handlers = &_iconv_null_conversion_handlers;
274      ic->data = ic->handlers->open (rptr, to, from);
275    }
276  else 
277    {
278      /* Use UCS-based conversion */
279      ic->handlers = &_iconv_ucs_conversion_handlers;
280      ic->data = ic->handlers->open (rptr, to, from);
281    }
282
283  if (ic->data == NULL)
284    {
285      _free_r (rptr, (void *)ic);
286      return (iconv_t)-1;
287    }
288
289  return (void *)ic;
290}
291
292/*
293 * _iconv_nls_open - open iconv descriptors for NLS.
294 *
295 * PARAMETERS:
296 *     struct _reent *rptr - process's reent structure;
297 *     const char *encoding - encoding name;
298 *     iconv_t *tomb - wchar -> encoding iconv descriptor pointer;
299 *     iconv_t *towc - encoding -> wchar iconv descriptor pointer;
300 *     int flag - perform encoding name resolving flag.
301 *
302 * DESCRIPTION:
303 *     Opens two iconv descriptors for 'encoding' -> wchar and
304 *     wchar -> 'encoding' iconv conversions. Function is used when locale or
305 *     wide-oriented stream is opened. If 'flag' is 0, don't perform encoding
306 *     name resolving ('encoding' must not be alias in this case).
307 *
308 * RETURN:
309 *     If successful - return 0, else set errno and return -1.
310 */
311int
312_iconv_nls_open (struct _reent *rptr,
313                        const char *encoding,
314                        iconv_t *tomb,
315                        iconv_t *towc,
316                        int flag)
317{
318  const char *wchar_encoding;
319
320  if (sizeof (wchar_t) > 2 && WCHAR_MAX > 0xFFFF)
321    wchar_encoding = "ucs_4_internal";
322  else if (sizeof (wchar_t) > 1 && WCHAR_MAX > 0xFF)
323    wchar_encoding = "ucs_2_internal";
324  else
325    wchar_encoding = ""; /* This shuldn't happen */
326
327  if (flag)
328    {
329      if ((*towc = _iconv_open_r (rptr, wchar_encoding, encoding)) == (iconv_t)-1)
330        return -1;
331   
332      if ((*tomb = _iconv_open_r (rptr, encoding, wchar_encoding)) == (iconv_t)-1)
333      {
334        _iconv_close_r (rptr, *towc);
335        return -1;
336      }
337    }
338  else
339    {
340      if ((*towc = iconv_open1 (rptr, wchar_encoding, encoding)) == (iconv_t)-1)
341        return -1;
342   
343      if ((*tomb = iconv_open1 (rptr, encoding, wchar_encoding)) == (iconv_t)-1)
344      {
345        _iconv_close_r (rptr, *towc);
346        return -1;
347      }
348    }
349
350  return 0;
351}
352
353#endif /* _MB_CAPABLE */
354
Note: See TracBrowser for help on using the repository browser.