source: trunk/libs/newlib/src/newlib/libc/iconv/ces/euc.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: 12.9 KB
Line 
1/*
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 "cesbi.h"
27
28#if defined (ICONV_TO_UCS_CES_EUC) \
29 || defined (ICONV_FROM_UCS_CES_EUC)
30
31#include <_ansi.h>
32#include <reent.h>
33#include <newlib.h>
34#include <string.h>
35#include <stdlib.h>
36#include <limits.h>
37#include <sys/types.h>
38#include "../lib/local.h"
39#include "../lib/ucsconv.h"
40#include "../lib/encnames.h"
41#include "../ccs/ccsnames.h"
42
43#define TYPE_EUC_JP 0
44#define TYPE_EUC_KR 1
45#define TYPE_EUC_TW 2
46
47#define MAX_CS_NUM 3
48 
49/* CS  description structure */ 
50typedef struct
51{
52  char *csname;
53  char *prefix;
54  int bytes;
55  int prefixbytes;
56  int touchmsb; /* If 1, msb will be set by euc converter */
57} euc_cs_desc_t;
58
59typedef struct
60{ 
61  int type;
62  int mb_cur_max;
63  euc_cs_desc_t *desc;
64 
65  void *data[MAX_CS_NUM];
66} euc_data_t;
67
68#if defined (_ICONV_TO_ENCODING_EUC_JP) \
69 || defined (_ICONV_FROM_ENCODING_EUC_JP) \
70 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
71static euc_cs_desc_t euc_jp_cs_desc[] =
72{
73  {ICONV_CCS_JIS_X0208_1990, "",     2, 0, 1},
74  {ICONV_CCS_JIS_X0201_1976, "\x8e", 1, 1, 0},
75  {ICONV_CCS_JIS_X0212_1990, "\x8f", 2, 1, 1},
76  {NULL, NULL, 0, 0}
77};
78#endif
79
80#if defined (_ICONV_TO_ENCODING_EUC_TW) \
81 || defined (_ICONV_FROM_ENCODING_EUC_TW) \
82 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
83static euc_cs_desc_t euc_tw_cs_desc [] =
84{
85  {ICONV_CCS_CNS11643_PLANE1,  "",         2, 0, 1},
86  {ICONV_CCS_CNS11643_PLANE2,  "\x8e\xa2", 2, 2, 1},
87  {ICONV_CCS_CNS11643_PLANE14, "\x8e\xae", 2, 2, 1},
88  {NULL, NULL, 0, 0}
89};
90#endif
91
92#if defined (_ICONV_TO_ENCODING_EUC_KR) \
93 || defined (_ICONV_FROM_ENCODING_EUC_KR) \
94 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
95static euc_cs_desc_t euc_kr_cs_desc [] =
96{
97  {ICONV_CCS_KSX1001,  "", 2, 0, 1},
98  {NULL, NULL, 0, 0}
99};
100#endif
101
102#if defined (ICONV_FROM_UCS_CES_EUC)
103static void *
104euc_from_ucs_init (struct _reent *rptr,
105                          const char *encoding)
106{
107  int i;
108  euc_data_t *data;
109
110  if ((data = (euc_data_t *)_calloc_r (rptr, 1, sizeof (euc_data_t))) == NULL)
111    return 0;
112 
113#if defined (_ICONV_TO_ENCODING_EUC_JP) \
114 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
115  if (strcmp (encoding, ICONV_ENCODING_EUC_JP) == 0)
116    {
117      data->type = TYPE_EUC_JP;
118      data->mb_cur_max = 3;
119      data->desc = &euc_jp_cs_desc[0];
120      goto ok;
121    }
122#endif
123#if defined (_ICONV_TO_ENCODING_EUC_KR) \
124 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
125  if (strcmp (encoding, ICONV_ENCODING_EUC_KR) == 0)
126    {
127      data->type = TYPE_EUC_KR;
128      data->mb_cur_max = 2;
129      data->desc = &euc_kr_cs_desc[0];
130      goto ok;
131    }
132#endif
133#if defined (_ICONV_TO_ENCODING_EUC_TW) \
134 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
135  if (strcmp (encoding, ICONV_ENCODING_EUC_TW) == 0)
136    {
137      data->type = TYPE_EUC_TW;
138      data->mb_cur_max = 4;
139      data->desc = &euc_tw_cs_desc[0];
140      goto ok;
141    }
142#endif
143 
144  goto error1;
145
146ok:
147  for (i = 0; data->desc[i].csname != NULL; i++)
148    {
149      data->data[i] = _iconv_from_ucs_ces_handlers_table.init (
150                                                        rptr,
151                                                        data->desc[i].csname);
152      if (data->data == NULL)
153        goto error;
154    } 
155
156  return data;
157   
158error:
159  _iconv_from_ucs_ces_handlers_table.close (rptr, data);
160  return NULL;
161error1:
162  _free_r (rptr, (void *)data);
163  return NULL;
164}
165
166static size_t
167euc_from_ucs_close (struct _reent *rptr,
168                           void *data)
169{
170  int i;
171  size_t res = 0;
172 
173  for (i = 0; i < MAX_CS_NUM; i++)
174    {
175      if (((euc_data_t *)data)->data[i] != NULL)
176        res |= _iconv_from_ucs_ces_handlers_table.close (
177                                                rptr,
178                                                ((euc_data_t *)data)->data[i]);
179    }
180  _free_r(rptr, data);
181
182  return res;
183}
184
185static size_t
186euc_convert_from_ucs (void *data,
187                             register ucs4_t in,
188                             unsigned char **outbuf,
189                             size_t *outbytesleft)
190{
191  int i;
192  int j;
193  int res;
194  unsigned char *outbuf1;
195  size_t outbytesleft1;
196  euc_data_t *d = (euc_data_t *)data;
197
198  if (in < 0x80) /* CS0 ASCII */
199    return _iconv_from_ucs_ces_handlers_us_ascii.convert_from_ucs (
200                                                 NULL,
201                                                 in,
202                                                 outbuf,
203                                                 outbytesleft);
204     
205  /* Try other CS */
206  for (i = 0; d->desc[i].csname != NULL; i++) 
207    {
208     
209      if (((int)*outbytesleft - d->desc[i].prefixbytes - d->desc[i].bytes) < 0)
210        {
211          char buf[ICONV_MB_LEN_MAX];
212          outbytesleft1 = ICONV_MB_LEN_MAX;
213          outbuf1 = &buf[0];
214          /* See wether this is right sequence */
215          res = 
216            (int)_iconv_from_ucs_ces_handlers_table.convert_from_ucs (
217                                                         d->data[i],
218                                                         in,
219                                                         &outbuf1,
220                                                         &outbytesleft1);
221          if (res > 0)
222            return (size_t)ICONV_CES_NOSPACE;
223
224          continue;
225        }
226     
227      outbuf1 = *outbuf + d->desc[i].prefixbytes;
228      outbytesleft1 = *outbytesleft - d->desc[i].prefixbytes;
229     
230      res = (int)_iconv_from_ucs_ces_handlers_table.convert_from_ucs (
231                                                     d->data[i],
232                                                     in,
233                                                     &outbuf1,
234                                                     &outbytesleft1);
235      if (res == d->desc[i].bytes)
236        {
237          for (j = 0; j < d->desc[i].prefixbytes; j++)
238            (*outbuf)[j] = d->desc[i].prefix[j];
239
240          if (d->desc[i].touchmsb)
241            for (j = 0; j < d->desc[i].bytes; j++)
242              {
243                if ((*outbuf)[j + d->desc[i].prefixbytes] & 0x80)
244                  return (size_t)ICONV_CES_INVALID_CHARACTER;
245                (*outbuf)[j + d->desc[i].prefixbytes] |= 0x80;
246              }
247
248          *outbuf = outbuf1;
249          *outbytesleft = outbytesleft1;
250         
251          return (size_t)(res + d->desc[i].bytes);
252        }
253    }
254
255  return (size_t)ICONV_CES_INVALID_CHARACTER;
256}
257#endif /* ICONV_FROM_UCS_CES_EUC */
258
259#if defined (ICONV_TO_UCS_CES_EUC)
260static void *
261euc_to_ucs_init (struct _reent *rptr,
262                        const char *encoding)
263{
264  int i;
265  euc_data_t *data;
266
267  if ((data = (euc_data_t *)_calloc_r (rptr, 1, sizeof (euc_data_t))) == NULL)
268    return 0;
269 
270#if defined (_ICONV_TO_ENCODING_EUC_JP) \
271 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
272  if (strcmp (encoding, ICONV_ENCODING_EUC_JP) == 0)
273    {
274      data->type = TYPE_EUC_JP;
275      data->mb_cur_max = 3;
276      data->desc = &euc_jp_cs_desc[0];
277      goto ok;
278    }
279#endif
280#if defined (_ICONV_TO_ENCODING_EUC_KR) \
281 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
282  if (strcmp (encoding, ICONV_ENCODING_EUC_KR) == 0)
283    {
284      data->type = TYPE_EUC_KR;
285      data->mb_cur_max = 2;
286      data->desc = &euc_kr_cs_desc[0];
287      goto ok;
288    }
289#endif
290#if defined (_ICONV_TO_ENCODING_EUC_TW) \
291 || defined (_ICONV_ENABLE_EXTERNAL_CCS)
292  if (strcmp (encoding, ICONV_ENCODING_EUC_TW) == 0)
293    {
294      data->type = TYPE_EUC_TW;
295      data->mb_cur_max = 4;
296      data->desc = &euc_tw_cs_desc[0];
297      goto ok;
298    }
299#endif
300 
301  goto error1;
302
303ok:
304  for (i = 0; data->desc[i].csname != NULL; i++)
305    {
306      data->data[i] = _iconv_to_ucs_ces_handlers_table.init (
307                                                        rptr,
308                                                        data->desc[i].csname);
309      if (data->data == NULL)
310        goto error;
311    } 
312
313  return data;
314   
315error:
316  _iconv_to_ucs_ces_handlers_table.close (rptr, data);
317  return NULL;
318error1:
319  _free_r (rptr, (void *)data);
320  return NULL;
321}
322
323static size_t
324euc_to_ucs_close (struct _reent *rptr,
325                         void *data)
326{
327  int i;
328  size_t res = 0;
329 
330  for (i = 0; i < MAX_CS_NUM; i++)
331    {
332      if (((euc_data_t *)data)->data[i] != NULL)
333        res |= _iconv_to_ucs_ces_handlers_table.close (
334                                                rptr,
335                                                ((euc_data_t *)data)->data[i]);
336    }
337  _free_r(rptr, data);
338
339  return res;
340}
341
342static ucs4_t
343euc_convert_to_ucs (void *data,
344                           const unsigned char **inbuf,
345                           size_t *inbytesleft)
346{
347  int i;
348  int j;
349  ucs4_t res;
350  unsigned char buf[ICONV_MB_LEN_MAX];
351  size_t inbytesleft1;
352  euc_data_t *d = (euc_data_t *)data;
353  unsigned char *inbuf1 = &buf[0];
354 
355  if (**inbuf < 0x80) /* CS0 is always ASCII */
356    return _iconv_to_ucs_ces_handlers_us_ascii.convert_to_ucs (
357                                                         NULL,
358                                                         inbuf,
359                                                         inbytesleft);
360 
361  for (i = 1; d->desc[i].csname != NULL; i++)
362    {
363      if (memcmp((const void *)(*inbuf),
364                 (const void *)d->desc[i].prefix,
365                 d->desc[i].prefixbytes) == 0)
366        {
367          if (((int)*inbytesleft - d->desc[i].prefixbytes - d->desc[i].bytes) < 0)
368            return (ucs4_t)ICONV_CES_BAD_SEQUENCE;
369
370          if (d->desc[i].touchmsb)
371            for (j = 0; j < d->desc[i].bytes; j++)
372              {
373                if (!((*inbuf)[j + d->desc[i].prefixbytes] & 0x80))
374                  return (ucs4_t)ICONV_CES_INVALID_CHARACTER;
375                inbuf1[j] = (*inbuf)[j + d->desc[i].prefixbytes] & 0x7F;
376              }
377          else
378            for (j = 0; j < d->desc[i].bytes; j++)
379              inbuf1[j] = (*inbuf)[j + d->desc[i].prefixbytes];
380         
381          inbytesleft1 = d->desc[i].bytes;
382         
383          res = _iconv_to_ucs_ces_handlers_table.convert_to_ucs (
384                                             d->data[i],
385                                             (const unsigned char **)&inbuf1,
386                                             &inbytesleft1);
387          if (((__int32_t)res) > 0)
388            {
389              *inbuf += d->desc[i].bytes +  d->desc[i].prefixbytes;
390              *inbytesleft -= d->desc[i].bytes + d->desc[i].prefixbytes;
391            }
392
393          return res;
394        }
395    }
396
397  /* Process CS1 */
398  if (((int)(*inbytesleft - d->desc[0].prefixbytes - d->desc[0].bytes)) < 0)
399    return (ucs4_t)ICONV_CES_BAD_SEQUENCE;
400 
401  if (d->desc[0].touchmsb)
402    for (j = 0; j < d->desc[0].bytes; j++)
403      {
404        if (!((*inbuf)[j + d->desc[0].prefixbytes] & 0x80))
405          return (ucs4_t)ICONV_CES_INVALID_CHARACTER;
406        inbuf1[j] = (*inbuf)[j] & 0x7F;
407      }
408  else
409    for (j = 0; j < d->desc[0].bytes; j++)
410      inbuf1[j] = (*inbuf)[j];
411
412  inbytesleft1 = d->desc[0].bytes;
413 
414  res = _iconv_to_ucs_ces_handlers_table.convert_to_ucs (
415                                        d->data[0],
416                                        (const unsigned char **)&inbuf1,
417                                        &inbytesleft1);
418  if (((__int32_t)res) > 0)
419    {
420      *inbuf += d->desc[0].bytes;
421      *inbytesleft -= d->desc[0].bytes;
422    }
423
424  return res;
425}
426#endif /* ICONV_TO_UCS_CES_EUC */
427
428static int
429euc_get_mb_cur_max (void *data)
430{
431  return ((euc_data_t *)data)->mb_cur_max;
432}
433
434#if defined (ICONV_FROM_UCS_CES_EUC)
435const iconv_from_ucs_ces_handlers_t
436_iconv_from_ucs_ces_handlers_euc =
437{
438  euc_from_ucs_init,
439  euc_from_ucs_close,
440  euc_get_mb_cur_max,
441  NULL,
442  NULL,
443  NULL,
444  euc_convert_from_ucs
445};
446#endif
447
448#if defined (ICONV_TO_UCS_CES_EUC)
449const iconv_to_ucs_ces_handlers_t
450_iconv_to_ucs_ces_handlers_euc = 
451{
452  euc_to_ucs_init,
453  euc_to_ucs_close,
454  euc_get_mb_cur_max,
455  NULL,
456  NULL,
457  NULL,
458  euc_convert_to_ucs
459};
460#endif
461
462#endif /* ICONV_TO_UCS_CES_EUC || ICONV_FROM_UCS_CES_EUC */
463
464
Note: See TracBrowser for help on using the repository browser.