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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [newlib/] [libc/] [iconv/] [lib/] [ucsconv.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 jlechner
/*
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
 
262
  if (direction == 0)
263
    {
264
      if (uc->to_ucs.handlers->get_state != NULL)
265
        uc->to_ucs.handlers->get_state (uc->to_ucs.data, state);
266
      else
267
        *state = ICONV_ZERO_MB_STATE_T;
268
    }
269
  else
270
    {
271
      if (uc->from_ucs.handlers->get_state != NULL)
272
        uc->from_ucs.handlers->get_state (uc->from_ucs.data, state);
273
      else
274
        *state = ICONV_ZERO_MB_STATE_T;
275
    }
276
 
277
  return;
278
}
279
 
280
 
281
static int
282
_DEFUN(ucs_based_conversion_set_state, (data, state, direction),
283
                                       _VOID_PTR data   _AND
284
                                       mbstate_t *state _AND
285
                                       int direction)
286
{
287
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
288
 
289
  if (direction == 0)
290
    {
291
      if (uc->to_ucs.handlers->set_state != NULL)
292
        return uc->to_ucs.handlers->set_state (uc->to_ucs.data, state);
293
    }
294
  else
295
    {
296
      if (uc->from_ucs.handlers->set_state != NULL)
297
        return uc->from_ucs.handlers->set_state (uc->from_ucs.data, state);
298
    }
299
 
300
  return 0;
301
}
302
 
303
static int
304
_DEFUN(ucs_based_conversion_is_stateful, (data, direction),
305
                                         _VOID_PTR data _AND
306
                                         int direction)
307
{
308
  iconv_ucs_conversion_t *uc = (iconv_ucs_conversion_t *)data;
309
 
310
  if (direction == 0)
311
    {
312
      if (uc->to_ucs.handlers->is_stateful != NULL)
313
        return uc->to_ucs.handlers->is_stateful (uc->to_ucs.data);
314
    }
315
  else
316
    {
317
      if (uc->from_ucs.handlers->is_stateful != NULL)
318
        return uc->from_ucs.handlers->is_stateful (uc->from_ucs.data);
319
    }
320
 
321
  return 0;
322
}
323
 
324
 
325
/* UCS-based conversion definition object */
326
_CONST iconv_conversion_handlers_t
327
_iconv_ucs_conversion_handlers =
328
{
329
  ucs_based_conversion_open,
330
  ucs_based_conversion_close,
331
  ucs_based_conversion_convert,
332
  ucs_based_conversion_get_state,
333
  ucs_based_conversion_set_state,
334
  ucs_based_conversion_get_mb_cur_max,
335
  ucs_based_conversion_is_stateful
336
};
337
 
338
 
339
/*
340
 * Supplementary functions.
341
 */
342
 
343
static int
344
_DEFUN(find_encoding_name, (searchee, names),
345
                           _CONST char *searchee _AND
346
                           _CONST char **names)
347
{
348
  _CONST char *p;
349
 
350
  for (p = *names; p != NULL; p = *(names++))
351
    if (strcmp (p, searchee) == 0)
352
      return 0;
353
 
354
  return -1;
355
}
356
 

powered by: WebSVN 2.1.0

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