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