2 * Copyright 2013 Garrett D'Amore <garrett@damore.org>
3 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
4 * Copyright (c) 2004 Tim J. Robbins. All rights reserved.
5 * Copyright (c) 2003 David Xu <davidxu@freebsd.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/types.h>
40 static size_t _GB2312_mbrtowc(wchar_t *_RESTRICT_KYWD
,
41 const char *_RESTRICT_KYWD
,
42 size_t, mbstate_t *_RESTRICT_KYWD
);
43 static int _GB2312_mbsinit(const mbstate_t *);
44 static size_t _GB2312_wcrtomb(char *_RESTRICT_KYWD
, wchar_t,
45 mbstate_t *_RESTRICT_KYWD
);
46 static size_t _GB2312_mbsnrtowcs(wchar_t *_RESTRICT_KYWD
,
47 const char **_RESTRICT_KYWD
, size_t, size_t,
48 mbstate_t *_RESTRICT_KYWD
);
49 static size_t _GB2312_wcsnrtombs(char *_RESTRICT_KYWD
,
50 const wchar_t **_RESTRICT_KYWD
, size_t, size_t,
51 mbstate_t *_RESTRICT_KYWD
);
60 _GB2312_init(struct lc_ctype
*lct
)
63 lct
->lc_mbrtowc
= _GB2312_mbrtowc
;
64 lct
->lc_wcrtomb
= _GB2312_wcrtomb
;
65 lct
->lc_mbsinit
= _GB2312_mbsinit
;
66 lct
->lc_mbsnrtowcs
= _GB2312_mbsnrtowcs
;
67 lct
->lc_wcsnrtombs
= _GB2312_wcsnrtombs
;
68 lct
->lc_max_mblen
= 2;
73 _GB2312_mbsinit(const mbstate_t *ps
)
76 return (ps
== NULL
|| ((const _GB2312State
*)ps
)->count
== 0);
80 _GB2312_check(const char *str
, size_t n
)
82 const uchar_t
*s
= (const uchar_t
*)str
;
85 /* Incomplete multibyte sequence */
87 if (s
[0] >= 0xa1 && s
[0] <= 0xfe) {
89 /* Incomplete multibyte sequence */
91 if (s
[1] < 0xa1 || s
[1] > 0xfe)
92 /* Invalid multibyte sequence */
95 } else if (s
[0] & 0x80) {
96 /* Invalid multibyte sequence */
103 _GB2312_mbrtowc(wchar_t *_RESTRICT_KYWD pwc
, const char *_RESTRICT_KYWD s
,
104 size_t n
, mbstate_t *_RESTRICT_KYWD ps
)
111 gs
= (_GB2312State
*)ps
;
113 if (gs
->count
< 0 || gs
->count
> sizeof (gs
->bytes
)) {
124 ncopy
= MIN(MIN(n
, MB_CUR_MAX
), sizeof (gs
->bytes
) - gs
->count
);
125 (void) memcpy(gs
->bytes
+ gs
->count
, s
, ncopy
);
128 s
= (char *)gs
->bytes
;
131 if ((len
= _GB2312_check(s
, n
)) < 0)
132 return ((size_t)len
);
136 wc
= (wc
<< 8) | (unsigned char)*s
++;
140 return (wc
== L
'\0' ? 0 : len
- ocount
);
144 _GB2312_wcrtomb(char *_RESTRICT_KYWD s
, wchar_t wc
,
145 mbstate_t *_RESTRICT_KYWD ps
)
149 gs
= (_GB2312State
*)ps
;
151 if (gs
->count
!= 0) {
157 /* Reset to initial shift state (no-op) */
160 *s
++ = (wc
>> 8) & 0xff;
169 _GB2312_mbsnrtowcs(wchar_t *_RESTRICT_KYWD dst
,
170 const char **_RESTRICT_KYWD src
, size_t nms
, size_t len
,
171 mbstate_t *_RESTRICT_KYWD ps
)
173 return (__mbsnrtowcs_std(dst
, src
, nms
, len
, ps
, _GB2312_mbrtowc
));
177 _GB2312_wcsnrtombs(char *_RESTRICT_KYWD dst
,
178 const wchar_t **_RESTRICT_KYWD src
, size_t nwc
, size_t len
,
179 mbstate_t *_RESTRICT_KYWD ps
)
181 return (__wcsnrtombs_std(dst
, src
, nwc
, len
, ps
, _GB2312_wcrtomb
));