OSDN Git Service

2004-06-25 Andrew Cagney <cagney@gnu.org>
[pf3gnuchains/pf3gnuchains3x.git] / newlib / libc / iconv / ces / iso-10646-ucs-2.c
1 /*-
2  * Copyright (c) 1999,2000
3  *    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  *    iconv (Charset Conversion Library) v2.0
27  */
28 #include "../lib/deps.h"
29
30 #ifdef _ICONV_CONVERTER_ISO_10646_UCS_2
31 #include "../lib/local.h"
32
33 #define out_char(ptr, ch) \
34     do { \
35         *(*(ptr))++ = ((ch) >> 8) & 0xFF; \
36         *(*(ptr))++ = (ch) & 0xFF; \
37     } while (0)
38
39 static ssize_t
40 _DEFUN(convert_from_ucs, (ces, in, outbuf, outbytesleft),
41                          struct iconv_ces *ces  _AND
42                          ucs_t in               _AND
43                          unsigned char **outbuf _AND
44                          size_t *outbytesleft)
45 {
46     size_t bytes;
47     int *state;
48
49     if (in == UCS_CHAR_NONE)
50             return 1; /* No state reinitialization for table charsets */
51     if (iconv_char32bit(in))
52         return -1;    /* No such character in UCS-2 */
53     bytes = *(state = (int *)(ces->data)) ? 2 : 4;
54     if (*outbytesleft < bytes)
55         return 0;     /* No space in the output buffer */
56     if (*state) {
57         out_char(outbuf, UCS_CHAR_ZERO_WIDTH_NBSP);
58         *state = 1;
59     }
60     out_char(outbuf, in);
61     *outbytesleft -= bytes;
62     return 1;
63 }
64
65 static __inline ucs_t
66 _DEFUN(msb, (buf), _CONST unsigned char *buf)
67 {
68     return (buf[0] << 8) | buf[1];
69 }
70
71 static ucs_t 
72 _DEFUN(convert_to_ucs, (ces, inbuf, inbytesleft),
73                        struct iconv_ces *ces        _AND
74                        _CONST unsigned char **inbuf _AND
75                        size_t *inbytesleft)
76 {
77     ucs_t res;
78     int *state, mark;
79
80     if (*inbytesleft < 2)
81         return UCS_CHAR_NONE; /* Not enough bytes in the input buffer */
82     state = (int *)(ces->data);
83     res = msb((_CONST unsigned char*)*inbuf);
84     switch (res) {
85         case UCS_CHAR_ZERO_WIDTH_NBSP:
86         *state = 1;
87         mark = 1;
88         break;
89         case UCS_CHAR_INVALID:
90         *state = 2;
91         mark = 1;
92         break;
93         default:
94         mark = 0;
95     }
96     if (mark) {
97         if (*inbytesleft < 4)
98             return UCS_CHAR_NONE; /* Not enough bytes in the input buffer */
99         *inbytesleft -= 2;
100         res = msb(*inbuf += 2);
101     }
102     if (*state == 2) {
103         res = (unsigned char)(*(*inbuf) ++);
104         res |= (unsigned char)(*(*inbuf) ++) << 8;
105     } else
106         *inbuf += 2;
107     *inbytesleft -= 2;
108     return res;
109 }
110
111 ICONV_CES_STATEFUL_MODULE_DECL(iso_10646_ucs_2);
112
113 #endif /* #ifdef _ICONV_CONVERTER_ISO_10646_UCS_2 */
114