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 * 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 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 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