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 */
43void *
44_icv_open()
45{
46	return ((void*)MAGIC_NUMBER);
47}
48
49
50/*
51 * Close; called from iconv_close
52 */
53void
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 */
64size_t
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
106ret:
107	*inbuf = (char *)ip;
108	*inbytesleft = ileft;
109	*outbuf = (char *)op;
110	*outbytesleft = oleft;
111
112	return (retval);
113}
114