1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 *
25 * This program assumes that all single byte coded characters will be either
26 * map to UTF-8 coded characters or illegal characters. Thus no replacement is
27 * assumed at the moment.
28 *
29 * This particular file is to cover conversions from various single byte
30 * codesets to UTF-8.
31 */
32
33
34 #include <stdlib.h>
35 #include <errno.h>
36 #include "sb_to_utf8.h"
37
38
39 void *
_icv_open()40 _icv_open()
41 {
42 return((void *)MAGIC_NUMBER);
43 }
44
45
46 void
_icv_close(int * cd)47 _icv_close(int *cd)
48 {
49 if (! cd || cd != (int *)MAGIC_NUMBER)
50 errno = EBADF;
51 }
52
53
54 size_t
_icv_iconv(int * cd,char ** inbuf,size_t * inbufleft,char ** outbuf,size_t * outbufleft)55 _icv_iconv(int *cd, char **inbuf, size_t *inbufleft, char **outbuf,
56 size_t *outbufleft)
57 {
58 size_t ret_val = 0;
59 unsigned char *ib;
60 unsigned char *ob;
61 unsigned char *ibtail;
62 unsigned char *obtail;
63
64 if (cd != (int *)MAGIC_NUMBER) {
65 errno = EBADF;
66 return((size_t)-1);
67 }
68
69 if (!inbuf || !(*inbuf))
70 return((size_t)0);
71
72 ib = (unsigned char *)*inbuf;
73 ob = (unsigned char *)*outbuf;
74 ibtail = ib + *inbufleft;
75 obtail = ob + *outbufleft;
76
77 while (ib < ibtail) {
78 register int i;
79 unsigned long u8;
80 signed char sz;
81
82 u8 = (unsigned long)sb_u8_tbl[*ib].u8;
83 sz = sb_u8_tbl[*ib].size;
84
85 if (sz == ICV_TYPE_ILLEGAL_CHAR) {
86 errno = EILSEQ;
87 ret_val = (size_t)-1;
88 break;
89 }
90
91 if ((u8 & ICV_UTF8_REPRESENTATION_ffff_mask) ==
92 ICV_UTF8_REPRESENTATION_fffe ||
93 (u8 & ICV_UTF8_REPRESENTATION_ffff_mask) ==
94 ICV_UTF8_REPRESENTATION_ffff ||
95 u8 > ICV_UTF8_REPRESENTATION_10fffd ||
96 (u8 >= ICV_UTF8_REPRESENTATION_d800 &&
97 u8 <= ICV_UTF8_REPRESENTATION_dfff) ||
98 (u8 >= ICV_UTF8_REPRESENTATION_fdd0 &&
99 u8 <= ICV_UTF8_REPRESENTATION_fdef)) {
100 /* This should not happen, if sb_u8_tbl is right. */
101 errno = EILSEQ;
102 ret_val = (size_t)-1;
103 break;
104 }
105
106 if ((obtail - ob) < sz) {
107 errno = E2BIG;
108 ret_val = (size_t)-1;
109 break;
110 }
111
112 for (i = 1; i <= sz; i++)
113 *ob++ = (unsigned int)((u8 >> ((sz - i) * 8)) & 0xff);
114 ib++;
115 }
116
117 *inbuf = (char *)ib;
118 *inbufleft = ibtail - ib;
119 *outbuf = (char *)ob;
120 *outbufleft = obtail - ob;
121
122 return(ret_val);
123 }
124