1*91e1e26aSAlexander Pyhalov /* 2*91e1e26aSAlexander Pyhalov * CDDL HEADER START 3*91e1e26aSAlexander Pyhalov * 4*91e1e26aSAlexander Pyhalov * The contents of this file are subject to the terms of the 5*91e1e26aSAlexander Pyhalov * Common Development and Distribution License (the "License"). 6*91e1e26aSAlexander Pyhalov * You may not use this file except in compliance with the License. 7*91e1e26aSAlexander Pyhalov * 8*91e1e26aSAlexander Pyhalov * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE 9*91e1e26aSAlexander Pyhalov * or http://www.opensolaris.org/os/licensing. 10*91e1e26aSAlexander Pyhalov * See the License for the specific language governing permissions 11*91e1e26aSAlexander Pyhalov * and limitations under the License. 12*91e1e26aSAlexander Pyhalov * 13*91e1e26aSAlexander Pyhalov * When distributing Covered Code, include this CDDL HEADER in each 14*91e1e26aSAlexander Pyhalov * file and include the License file at src/OPENSOLARIS.LICENSE. 15*91e1e26aSAlexander Pyhalov * If applicable, add the following below this CDDL HEADER, with the 16*91e1e26aSAlexander Pyhalov * fields enclosed by brackets "[]" replaced with your own identifying 17*91e1e26aSAlexander Pyhalov * information: Portions Copyright [yyyy] [name of copyright owner] 18*91e1e26aSAlexander Pyhalov * 19*91e1e26aSAlexander Pyhalov * CDDL HEADER END 20*91e1e26aSAlexander Pyhalov */ 21*91e1e26aSAlexander Pyhalov /* 22*91e1e26aSAlexander Pyhalov * Copyright (c) 2008, by Sun Microsystems, Inc. 23*91e1e26aSAlexander Pyhalov * All rights reserved. 24*91e1e26aSAlexander Pyhalov */ 25*91e1e26aSAlexander Pyhalov 26*91e1e26aSAlexander Pyhalov #include <stdio.h> 27*91e1e26aSAlexander Pyhalov #include <errno.h> 28*91e1e26aSAlexander Pyhalov #include <stdlib.h> 29*91e1e26aSAlexander Pyhalov #include <sys/types.h> 30*91e1e26aSAlexander Pyhalov #define __NEED_VISCII_2_UNI__ 31*91e1e26aSAlexander Pyhalov #include <unicode_viscii.h> /* Unicode to viscii mapping table */ 32*91e1e26aSAlexander Pyhalov #include "common_defs.h" 33*91e1e26aSAlexander Pyhalov 34*91e1e26aSAlexander Pyhalov 35*91e1e26aSAlexander Pyhalov typedef struct _icv_state { 36*91e1e26aSAlexander Pyhalov char keepc[4]; /* maximum # byte of UCS code */ 37*91e1e26aSAlexander Pyhalov int _errno; /* internal errno */ 38*91e1e26aSAlexander Pyhalov } _iconv_st; 39*91e1e26aSAlexander Pyhalov 40*91e1e26aSAlexander Pyhalov 41*91e1e26aSAlexander Pyhalov 42*91e1e26aSAlexander Pyhalov /* 43*91e1e26aSAlexander Pyhalov * Open; called from iconv_open() 44*91e1e26aSAlexander Pyhalov */ 45*91e1e26aSAlexander Pyhalov void * 46*91e1e26aSAlexander Pyhalov _icv_open() 47*91e1e26aSAlexander Pyhalov { 48*91e1e26aSAlexander Pyhalov _iconv_st *st; 49*91e1e26aSAlexander Pyhalov 50*91e1e26aSAlexander Pyhalov if ((st = (_iconv_st *)malloc(sizeof(_iconv_st))) == NULL) { 51*91e1e26aSAlexander Pyhalov errno = ENOMEM; 52*91e1e26aSAlexander Pyhalov return ((void *) -1); 53*91e1e26aSAlexander Pyhalov } 54*91e1e26aSAlexander Pyhalov 55*91e1e26aSAlexander Pyhalov st->_errno = 0; 56*91e1e26aSAlexander Pyhalov return ((void *) st); 57*91e1e26aSAlexander Pyhalov } 58*91e1e26aSAlexander Pyhalov 59*91e1e26aSAlexander Pyhalov 60*91e1e26aSAlexander Pyhalov /* 61*91e1e26aSAlexander Pyhalov * Close; called from iconv_close() 62*91e1e26aSAlexander Pyhalov */ 63*91e1e26aSAlexander Pyhalov void 64*91e1e26aSAlexander Pyhalov _icv_close(_iconv_st *st) 65*91e1e26aSAlexander Pyhalov { 66*91e1e26aSAlexander Pyhalov if (!st) 67*91e1e26aSAlexander Pyhalov errno = EBADF; 68*91e1e26aSAlexander Pyhalov else 69*91e1e26aSAlexander Pyhalov free(st); 70*91e1e26aSAlexander Pyhalov } 71*91e1e26aSAlexander Pyhalov 72*91e1e26aSAlexander Pyhalov 73*91e1e26aSAlexander Pyhalov /* 74*91e1e26aSAlexander Pyhalov * Actual conversion; called from iconv() 75*91e1e26aSAlexander Pyhalov */ 76*91e1e26aSAlexander Pyhalov size_t 77*91e1e26aSAlexander Pyhalov _icv_iconv(_iconv_st *st, char **inbuf, size_t *inbytesleft, 78*91e1e26aSAlexander Pyhalov char **outbuf, size_t *outbytesleft) 79*91e1e26aSAlexander Pyhalov { 80*91e1e26aSAlexander Pyhalov 81*91e1e26aSAlexander Pyhalov #ifdef DEBUG 82*91e1e26aSAlexander Pyhalov fprintf(stderr, "========== iconv(): viscii -->UTF-8 ==========\n"); 83*91e1e26aSAlexander Pyhalov #endif 84*91e1e26aSAlexander Pyhalov if (st == NULL) { 85*91e1e26aSAlexander Pyhalov errno = EBADF; 86*91e1e26aSAlexander Pyhalov return ((size_t) -1); 87*91e1e26aSAlexander Pyhalov } 88*91e1e26aSAlexander Pyhalov 89*91e1e26aSAlexander Pyhalov if (inbuf == NULL || *inbuf == NULL) { /* Reset request. */ 90*91e1e26aSAlexander Pyhalov st->_errno = 0; 91*91e1e26aSAlexander Pyhalov return ((size_t) 0); 92*91e1e26aSAlexander Pyhalov } 93*91e1e26aSAlexander Pyhalov 94*91e1e26aSAlexander Pyhalov st->_errno = 0; /* reset internal errno */ 95*91e1e26aSAlexander Pyhalov errno = 0; /* reset external errno */ 96*91e1e26aSAlexander Pyhalov 97*91e1e26aSAlexander Pyhalov /* convert viscii encoding to UTF-8 */ 98*91e1e26aSAlexander Pyhalov while (*inbytesleft > 0 && *outbytesleft > 0) { 99*91e1e26aSAlexander Pyhalov unsigned long uni = 0; 100*91e1e26aSAlexander Pyhalov 101*91e1e26aSAlexander Pyhalov viscii_2_uni((unsigned char*)*inbuf, &uni); 102*91e1e26aSAlexander Pyhalov if (uni < 0x80) { 103*91e1e26aSAlexander Pyhalov *(*outbuf)++ = (char)uni; 104*91e1e26aSAlexander Pyhalov (*outbytesleft) -= 1; 105*91e1e26aSAlexander Pyhalov } else if (uni >= 0x0080 && uni <= 0x07ff) { 106*91e1e26aSAlexander Pyhalov if (*outbytesleft < 2 ) { 107*91e1e26aSAlexander Pyhalov errno = E2BIG; 108*91e1e26aSAlexander Pyhalov return((size_t)-1); 109*91e1e26aSAlexander Pyhalov } 110*91e1e26aSAlexander Pyhalov *(*outbuf)++ = (char)((uni >> 6) & 0x1f) | 0xc0; 111*91e1e26aSAlexander Pyhalov *(*outbuf)++ = (char)(uni & 0x3f) | 0x80; 112*91e1e26aSAlexander Pyhalov *outbytesleft -= 2; 113*91e1e26aSAlexander Pyhalov } else if (uni >= 0x0800 && uni <= 0xffff) { 114*91e1e26aSAlexander Pyhalov if (*outbytesleft < 3) { 115*91e1e26aSAlexander Pyhalov errno = E2BIG; 116*91e1e26aSAlexander Pyhalov return((size_t)-1); 117*91e1e26aSAlexander Pyhalov } 118*91e1e26aSAlexander Pyhalov *(*outbuf)++ = (char)((uni >> 12) & 0xf) | 0xe0; 119*91e1e26aSAlexander Pyhalov *(*outbuf)++ = (char)((uni >>6) & 0x3f) | 0x80; 120*91e1e26aSAlexander Pyhalov *(*outbuf)++ = (char)(uni & 0x3f) | 0x80; 121*91e1e26aSAlexander Pyhalov *outbytesleft -= 3; 122*91e1e26aSAlexander Pyhalov } 123*91e1e26aSAlexander Pyhalov 124*91e1e26aSAlexander Pyhalov (*inbuf)++; 125*91e1e26aSAlexander Pyhalov (*inbytesleft)--; 126*91e1e26aSAlexander Pyhalov 127*91e1e26aSAlexander Pyhalov } 128*91e1e26aSAlexander Pyhalov 129*91e1e26aSAlexander Pyhalov if ( *inbytesleft > 0 && *outbytesleft <= 0 ) { 130*91e1e26aSAlexander Pyhalov errno = E2BIG; 131*91e1e26aSAlexander Pyhalov return ((size_t)-1); 132*91e1e26aSAlexander Pyhalov } 133*91e1e26aSAlexander Pyhalov 134*91e1e26aSAlexander Pyhalov return ((size_t)(*inbytesleft)); 135*91e1e26aSAlexander Pyhalov } 136