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) 2008, by Sun Microsystems, Inc.
23 * All rights reserved.
24 */
25 #include <stdio.h>
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <sys/types.h>
29 #define __NEED_VISCII_2_UNI__
30 #include <unicode_viscii.h> /* Unicode to viscii mapping table */
31 #include "common_defs.h"
32
33
34 typedef struct _icv_state {
35 int _errno; /* internal errno */
36 } _iconv_st;
37
38
39 /*
40 * Open; called from iconv_open()
41 */
42 void *
_icv_open()43 _icv_open()
44 {
45 _iconv_st *st;
46
47 if ((st = (_iconv_st *)malloc(sizeof(_iconv_st))) == NULL) {
48 errno = ENOMEM;
49 return ((void *) -1);
50 }
51 st->_errno = 0;
52 return ((void *) st);
53 }
54
55
56 /*
57 * Close; called from iconv_close()
58 */
59 void
_icv_close(_iconv_st * st)60 _icv_close(_iconv_st *st)
61 {
62 if (!st)
63 errno = EBADF;
64 else
65 free(st);
66 }
67
68
69 /*
70 * Actual conversion; called from iconv()
71 */
72 size_t
_icv_iconv(_iconv_st * st,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)73 _icv_iconv(_iconv_st *st, char **inbuf, size_t *inbytesleft,
74 char **outbuf, size_t *outbytesleft)
75 {
76 #ifdef DEBUG
77 fprintf(stderr, "========== iconv(): viscii -->UCS-2 ==========\n");
78 #endif
79 if (st == NULL) {
80 errno = EBADF;
81 return ((size_t) -1);
82 }
83
84 if (inbuf == NULL || *inbuf == NULL) { /* Reset request. */
85 st->_errno = 0;
86 return ((size_t) 0);
87 }
88
89 st->_errno = 0; /* reset internal errno */
90 errno = 0; /* reset external errno */
91
92 /* convert viscii encoding to UCS-2 */
93 while (*inbytesleft > 0 && *outbytesleft > 1) {
94 unsigned long uni = 0;
95
96 viscii_2_uni((unsigned char*)*inbuf, &uni);
97 #if defined(UCS_2LE)
98 *(*outbuf)++ = (unsigned char)(uni&0xff);
99 *(*outbuf)++ = (unsigned char)((uni>>8)&0xff);
100 #else
101 *(*outbuf)++ = (unsigned char)((uni>>8)&0xff);
102 *(*outbuf)++ = (unsigned char)((uni)&0xff);
103 #endif
104 (*outbytesleft) -= 2;
105 (*inbuf)++;
106 (*inbytesleft)--;
107
108 }
109
110 if ( *inbytesleft > 0 && *outbytesleft <= 1 ) {
111 errno = E2BIG;
112 return ((size_t)-1);
113 }
114
115 return ((size_t)(*inbytesleft));
116
117 }
118