OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libc/] [iconv/] [lib/] [ucsconv.c] - Blame information for rev 262

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/*
2
 * Copyright (c) 2003-2004, Artem B. Bityuckiy
3
 * Copyright (c) 1999,2000, Konstantin Chuguev. All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
 * SUCH DAMAGE.
25
 */
26
#include <_ansi.h>
27
#include <reent.h>
28
#include <sys/types.h>
29
#include <errno.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#include "local.h"
33
#include "conv.h"
34
#include "ucsconv.h"
35
 
36
static int fake_data;
37
 
38
static int
39
_EXFUN(find_encoding_name, (_CONST char *searchee,
40
                            _CONST char **names));
41
 
42
 
43
/*
44
 * UCS-based conversion interface functions implementation.
45
 */
46
 
47
static _VOID_PTR
48
_DEFUN(ucs_based_conversion_open, (rptr, to, from),
49
                                  struct _reent *rptr _AND
50
                                  _CONST char *to     _AND
51
                                  _CONST char *from)
52
{
53
  iconv_ucs_conversion_t *uc;
54
  _CONST iconv_to_ucs_ces_t   *to_ucs_bices;
55
  _CONST iconv_from_ucs_ces_t *from_ucs_bices;
56
 
57
  uc = (iconv_ucs_conversion_t *)
58
             _calloc_r (rptr, 1, sizeof (iconv_ucs_conversion_t));
59
  if (uc == NULL)
60
    return NULL;
61
 
62
  /*
63
   * Find CES converter for "from" encoding ("from" source encoding corresponds
64
   * to "to_ucs" CES converter).
65
   */
66
  for (to_ucs_bices = &_iconv_to_ucs_ces[0];
67
       to_ucs_bices->names != NULL;
68
       to_ucs_bices++)
69
    {
70
      if (find_encoding_name (from, to_ucs_bices->names) == 0)
71
        break;
72
    }
73
 
74
  /*
75
   * Find CES converter for "to" encoding ("to" source encoding corresponds
76
   * to "from_ucs" CES converter).
77
   */
78
  for (from_ucs_bices = &_iconv_from_ucs_ces[0];
79
       from_ucs_bices->names != NULL;
80
       from_ucs_bices++)
81
    {
82
      if (find_encoding_name (to, from_ucs_bices->names) == 0)
83
        break;
84
    }
85
 
86
  if (to_ucs_bices->names == NULL || from_ucs_bices->names == NULL)
87
    goto error;
88
 
89
  uc->to_ucs.handlers = to_ucs_bices->handlers;
90
  uc->from_ucs.handlers = from_ucs_bices->handlers;
91
 
92
  /* Initialize "to UCS" CES converter */
93
  if (to_ucs_bices->handlers->init != NULL)
94
    {
95
      uc->to_ucs.data = to_ucs_bices->handlers->init (rptr, from);
96
      if (uc->to_ucs.data == NULL)
97
        goto error;
98
    }
99
  else
100
    uc->to_ucs.data = (_VOID_PTR)&fake_data;
101
 
102
 
103
  /* Initialize "from UCS" CES converter */
104
  if (from_ucs_bices->handlers->init != NULL)
105
    {
106
      uc->from_ucs.data = from_ucs_bices->handlers->init (rptr, to);
107
      if (uc->from_ucs.data == NULL)
108
        goto error;
109
    }
110
  else
111
    uc->from_ucs.data = (_VOID_PTR)&fake_data;
112
 
113
  return uc;
114
 
115
error:
116
  if (uc->to_ucs.data != NULL && uc->to_ucs.handlers->close != NULL)
117
    uc->to_ucs.handlers->close (rptr, uc->to_ucs.data);
118
 
119
  _free_r (rptr, (_VOID_PTR)uc);
120
 
121
  return NULL;
122
}
123
 
124
 
125
static size_t
126
_DEFUN(ucs_based_conversion_close, (rptr, data),
127
                                   struct _reent *rptr _AND
128
                                   _VOID_PTR data)
129
{
130
  iconv_ucs_conversion_t *uc;
131
  size_t res = 0;
132
 
133
  uc = (iconv_ucs_conversion_t *)data;
134
 
135
  if (uc->from_ucs.handlers->close != NULL)
136
    res = uc->from_ucs.handlers->close (rptr, uc->from_ucs.data);
137
  if (uc->to_ucs.handlers->close != NULL)
138
    res |= uc->to_ucs.handlers->close (rptr, uc->to_ucs.data);
139
 
140
  _free_r (rptr, (_VOID_PTR)data);
141
 
142
  return res;
143
}
144
 
145
 
146
static size_t
147
_DEFUN(ucs_based_conversion_convert,
148
                 (rptr, data, inbuf, inbytesleft, outbuf, outbytesleft, flags),
149
                 struct _reent *rptr          _AND
150
                 _VOID_PTR data               _AND
151
                 _CONST unsigned char **inbuf _AND
152
                 size_t *inbytesleft          _AND
153
                 unsigned char **outbuf       _AND
154
                 size_t *outbytesleft         _AND
155
                 int flags)
156
{
157
  unsigned char outbuf1[ICONV_MB_LEN_MAX];
158
  unsigned char *poutbuf1;
159
  size_t res = 0;
160
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
161
 
162
  while (*inbytesleft > 0)
163
    {
164
      register size_t bytes;
165
      register ucs4_t ch;
166
      _CONST unsigned char *inbuf_save = *inbuf;
167
      size_t inbyteslef_save = *inbytesleft;
168
 
169
      if (*outbytesleft == 0)
170
        {
171
          __errno_r (rptr) = E2BIG;
172
          return (size_t)-1;
173
        }
174
 
175
      ch = uc->to_ucs.handlers->convert_to_ucs (uc->to_ucs.data,
176
                                                inbuf, inbytesleft);
177
 
178
      if (ch == (ucs4_t)ICONV_CES_BAD_SEQUENCE)
179
        {
180
          __errno_r (rptr) = EINVAL;
181
          return (size_t)-1;
182
        }
183
 
184
      if (ch == (ucs4_t)ICONV_CES_INVALID_CHARACTER)
185
        {
186
          __errno_r (rptr) = EILSEQ;
187
          return (size_t)-1;
188
        }
189
 
190
      if (flags & ICONV_DONT_SAVE_BIT)
191
        {
192
          poutbuf1 = &outbuf1[0];
193
          outbuf = &poutbuf1;
194
        }
195
 
196
      bytes = uc->from_ucs.handlers->convert_from_ucs (uc->from_ucs.data, ch,
197
                                                       outbuf, outbytesleft);
198
 
199
      if (bytes == (size_t)ICONV_CES_NOSPACE)
200
        {
201
          *inbuf = inbuf_save;
202
          *inbytesleft = inbyteslef_save;
203
          __errno_r (rptr) = E2BIG;
204
          return (size_t)-1;
205
        }
206
      else if (bytes == (size_t)ICONV_CES_INVALID_CHARACTER)
207
        {
208
          if (flags & ICONV_FAIL_BIT)
209
            {
210
              /* Generate error */
211
              __errno_r (rptr) = EILSEQ;
212
              return (size_t)-1;
213
            }
214
          /*
215
           * For this case SUSv3 stands: "if iconv() encounters a character in the
216
           * input buffer that is valid, but for which an identical character does
217
           * not exist in the target encoding, iconv() shall perform an
218
           * implementation-defined conversion on this character".
219
           * Don't generate error, just write default character.
220
           */
221
          bytes = uc->from_ucs.handlers->convert_from_ucs (
222
                                         uc->from_ucs.data,
223
                                         (ucs4_t)DEFAULT_CHARACTER,
224
                                         outbuf,
225
                                         outbytesleft);
226
          if ((__int32_t)bytes < 0)
227
            {
228
              __errno_r (rptr) = E2BIG;
229
              return (size_t)-1;
230
            }
231
 
232
          res += 1;
233
        }
234
    }
235
 
236
  return res;
237
}
238
 
239
 
240
static int
241
_DEFUN(ucs_based_conversion_get_mb_cur_max, (data, direction),
242
                                            _VOID_PTR data _AND
243
                                            int direction)
244
{
245
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
246
 
247
  if (direction == 0)
248
    return uc->to_ucs.handlers->get_mb_cur_max (uc->to_ucs.data);
249
  else
250
    return uc->from_ucs.handlers->get_mb_cur_max (uc->from_ucs.data);
251
}
252
 
253
 
254
static _VOID
255
_DEFUN(ucs_based_conversion_get_state, (data, state, direction),
256
                                       _VOID_PTR data   _AND
257
                                       mbstate_t *state _AND
258
                                       int direction)
259
{
260
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
261
  mbstate_t nullstate = ICONV_ZERO_MB_STATE_T;
262
 
263
  if (direction == 0)
264
    {
265
      if (uc->to_ucs.handlers->get_state != NULL)
266
        uc->to_ucs.handlers->get_state (uc->to_ucs.data, state);
267
      else
268
        *state = nullstate; /* internal copy */
269
    }
270
  else
271
    {
272
      if (uc->from_ucs.handlers->get_state != NULL)
273
        uc->from_ucs.handlers->get_state (uc->from_ucs.data, state);
274
      else
275
        *state = nullstate; /* internal copy */
276
    }
277
 
278
  return;
279
}
280
 
281
 
282
static int
283
_DEFUN(ucs_based_conversion_set_state, (data, state, direction),
284
                                       _VOID_PTR data   _AND
285
                                       mbstate_t *state _AND
286
                                       int direction)
287
{
288
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
289
 
290
  if (direction == 0)
291
    {
292
      if (uc->to_ucs.handlers->set_state != NULL)
293
        return uc->to_ucs.handlers->set_state (uc->to_ucs.data, state);
294
    }
295
  else
296
    {
297
      if (uc->from_ucs.handlers->set_state != NULL)
298
        return uc->from_ucs.handlers->set_state (uc->from_ucs.data, state);
299
    }
300
 
301
  return 0;
302
}
303
 
304
static int
305
_DEFUN(ucs_based_conversion_is_stateful, (data, direction),
306
                                         _VOID_PTR data _AND
307
                                         int direction)
308
{
309
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
310
 
311
  if (direction == 0)
312
    {
313
      if (uc->to_ucs.handlers->is_stateful != NULL)
314
        return uc->to_ucs.handlers->is_stateful (uc->to_ucs.data);
315
    }
316
  else
317
    {
318
      if (uc->from_ucs.handlers->is_stateful != NULL)
319
        return uc->from_ucs.handlers->is_stateful (uc->from_ucs.data);
320
    }
321
 
322
  return 0;
323
}
324
 
325
 
326
/* UCS-based conversion definition object */
327
_CONST iconv_conversion_handlers_t
328
_iconv_ucs_conversion_handlers =
329
{
330
  ucs_based_conversion_open,
331
  ucs_based_conversion_close,
332
  ucs_based_conversion_convert,
333
  ucs_based_conversion_get_state,
334
  ucs_based_conversion_set_state,
335
  ucs_based_conversion_get_mb_cur_max,
336
  ucs_based_conversion_is_stateful
337
};
338
 
339
 
340
/*
341
 * Supplementary functions.
342
 */
343
 
344
static int
345
_DEFUN(find_encoding_name, (searchee, names),
346
                           _CONST char *searchee _AND
347
                           _CONST char **names)
348
{
349
  _CONST char *p;
350
 
351
  for (p = *names; p != NULL; p = *(names++))
352
    if (strcmp (p, searchee) == 0)
353
      return 0;
354
 
355
  return -1;
356
}
357
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.