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 (c) 1994, 1995 by Sun Microsystems, Inc.
23 * Copyright (c) 1994, Nihon Sun Microsystems K.K.
24 * All Rights Reserved.
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include <ctype.h>
31
32 #define MAGIC_NUMBER (0x216513)
33 #define ERR_RETURN (-1) /* result code on error */
34
35 #define GET(c) ((c) = *ip, ip++, ileft--)
36 #define PUT(c) (*op = (c), op++, oleft--)
37 #define UNGET() (ip--, ileft++)
38
39
40 /*
41 * Open; called from iconv_open()
42 */
43 void *
_icv_open()44 _icv_open()
45 {
46 return ((void*)MAGIC_NUMBER);
47 }
48
49
50 /*
51 * Close; called from iconv_close
52 */
53 void
_icv_close(int * cd)54 _icv_close(int* cd)
55 {
56 if (!cd || cd != (int*)MAGIC_NUMBER)
57 errno = EBADF;
58 }
59
60
61 /*
62 * Actual conversion; called from iconv()
63 */
64 size_t
_icv_iconv(int * cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)65 _icv_iconv(int* cd, char **inbuf, size_t *inbytesleft,
66 char **outbuf, size_t *outbytesleft)
67 {
68 unsigned char *ip, ic, *op;
69 size_t ileft, oleft;
70 size_t retval = 0;
71
72 if (!cd || cd != (int*)MAGIC_NUMBER)
73 {
74 errno = EBADF;
75 return((size_t)ERR_RETURN);
76 }
77
78 if ((inbuf == 0) || (*inbuf == 0))
79 return((size_t)0);
80
81 ip = (unsigned char*)*inbuf;
82 op = (unsigned char *)*outbuf;
83 ileft = *inbytesleft;
84 oleft = *outbytesleft;
85
86 /*
87 * Main loop; basically 1 loop per 1 input byte
88 */
89
90 while (ileft > 0) {
91 GET(ic);
92 if (oleft < 1) {
93 UNGET();
94 errno = E2BIG;
95 retval = ERR_RETURN;
96 goto ret;
97 }
98 if (isascii(ic))
99 PUT(ic);
100 else {
101 PUT('_');
102 retval++;
103 }
104 }
105
106 ret:
107 *inbuf = (char *)ip;
108 *inbytesleft = ileft;
109 *outbuf = (char *)op;
110 *outbytesleft = oleft;
111
112 return (retval);
113 }
114