116d86563SAlexander Pyhalov /*
216d86563SAlexander Pyhalov * CDDL HEADER START
316d86563SAlexander Pyhalov *
416d86563SAlexander Pyhalov * The contents of this file are subject to the terms of the
516d86563SAlexander Pyhalov * Common Development and Distribution License (the "License").
616d86563SAlexander Pyhalov * You may not use this file except in compliance with the License.
716d86563SAlexander Pyhalov *
816d86563SAlexander Pyhalov * You can obtain a copy of the license at src/OPENSOLARIS.LICENSE
916d86563SAlexander Pyhalov * or http://www.opensolaris.org/os/licensing.
1016d86563SAlexander Pyhalov * See the License for the specific language governing permissions
1116d86563SAlexander Pyhalov * and limitations under the License.
1216d86563SAlexander Pyhalov *
1316d86563SAlexander Pyhalov * When distributing Covered Code, include this CDDL HEADER in each
1416d86563SAlexander Pyhalov * file and include the License file at src/OPENSOLARIS.LICENSE.
1516d86563SAlexander Pyhalov * If applicable, add the following below this CDDL HEADER, with the
1616d86563SAlexander Pyhalov * fields enclosed by brackets "[]" replaced with your own identifying
1716d86563SAlexander Pyhalov * information: Portions Copyright [yyyy] [name of copyright owner]
1816d86563SAlexander Pyhalov *
1916d86563SAlexander Pyhalov * CDDL HEADER END
2016d86563SAlexander Pyhalov */
2116d86563SAlexander Pyhalov /*
2216d86563SAlexander Pyhalov #include <stdlib.h>
2316d86563SAlexander Pyhalov * Copyright (c) 1997, by Sun Microsystems, Inc.
2416d86563SAlexander Pyhalov * All rights reserved.
2516d86563SAlexander Pyhalov */
2616d86563SAlexander Pyhalov
2716d86563SAlexander Pyhalov
2816d86563SAlexander Pyhalov /*
2916d86563SAlexander Pyhalov Converts From: ISO2022-CN-EXT encoding.
3016d86563SAlexander Pyhalov Converts To: Taiwanese EUC encoding ( CNS11643 ) and big5 encoding
3116d86563SAlexander Pyhalov
3216d86563SAlexander Pyhalov */
3316d86563SAlexander Pyhalov
3416d86563SAlexander Pyhalov #include "iso2022-cn.h"
3516d86563SAlexander Pyhalov
3616d86563SAlexander Pyhalov /* Forward reference the functions constrained to the scope of this file */
3716d86563SAlexander Pyhalov static int process_esc_seq(char, _iconv_st *);
3816d86563SAlexander Pyhalov static int ascii_to_euc(char, _iconv_st *, unsigned char **, size_t *);
3916d86563SAlexander Pyhalov static int iscns( _iconv_st * );
4016d86563SAlexander Pyhalov
4116d86563SAlexander Pyhalov
4216d86563SAlexander Pyhalov extern int errno;
4316d86563SAlexander Pyhalov
4416d86563SAlexander Pyhalov /*
4516d86563SAlexander Pyhalov * _icv_open: Called from iconv_open(). Allocates and initializes _iconv_st
4616d86563SAlexander Pyhalov * structure. Returns pointer to the structure as (void *).
4716d86563SAlexander Pyhalov */
4816d86563SAlexander Pyhalov
4916d86563SAlexander Pyhalov
5016d86563SAlexander Pyhalov void *
_icv_open()5116d86563SAlexander Pyhalov _icv_open()
5216d86563SAlexander Pyhalov {
5316d86563SAlexander Pyhalov _iconv_st *st;
5416d86563SAlexander Pyhalov
5516d86563SAlexander Pyhalov /* Allocate */
5616d86563SAlexander Pyhalov if (( st = (_iconv_st *) malloc( sizeof( _iconv_st ))) == NULL ){
5716d86563SAlexander Pyhalov errno = ENOMEM;
5816d86563SAlexander Pyhalov return ((void *) -1);
5916d86563SAlexander Pyhalov }
6016d86563SAlexander Pyhalov
6116d86563SAlexander Pyhalov /* Initialize */
6216d86563SAlexander Pyhalov st->Sfunc = SI;
6316d86563SAlexander Pyhalov st->SSfunc = NONE;
6416d86563SAlexander Pyhalov st->ESCstate = OFF;
6516d86563SAlexander Pyhalov st->firstbyte = True;
6616d86563SAlexander Pyhalov st->numsav = 0;
67*f642269fSToomas Soome st->SOcharset = 0; /* no default charset */
68*f642269fSToomas Soome st->SS2charset = 0; /* no default charset */
69*f642269fSToomas Soome st->SS3charset = 0; /* no default charset */
7016d86563SAlexander Pyhalov st->nonidcount = 0;
7116d86563SAlexander Pyhalov st->_errno = 0;
7216d86563SAlexander Pyhalov
7316d86563SAlexander Pyhalov /* Return struct */
7416d86563SAlexander Pyhalov return ((void *) st);
7516d86563SAlexander Pyhalov }
7616d86563SAlexander Pyhalov
7716d86563SAlexander Pyhalov
7816d86563SAlexander Pyhalov
7916d86563SAlexander Pyhalov /*
8016d86563SAlexander Pyhalov * _icv_close: Called from iconv_close(). Frees the _iconv_st structure as
8116d86563SAlexander Pyhalov * pointed by the argument.
8216d86563SAlexander Pyhalov */
8316d86563SAlexander Pyhalov
8416d86563SAlexander Pyhalov void
_icv_close(_iconv_st * st)8516d86563SAlexander Pyhalov _icv_close(_iconv_st *st)
8616d86563SAlexander Pyhalov {
8716d86563SAlexander Pyhalov if (st == NULL )
8816d86563SAlexander Pyhalov errno = EBADF;
8916d86563SAlexander Pyhalov else
9016d86563SAlexander Pyhalov free(st);
9116d86563SAlexander Pyhalov }
9216d86563SAlexander Pyhalov
9316d86563SAlexander Pyhalov
9416d86563SAlexander Pyhalov /*
9516d86563SAlexander Pyhalov * _icv_iconv: Called from iconv(). Does the convertion from ISO2022-CN-EXT
9616d86563SAlexander Pyhalov * to CNS11643
9716d86563SAlexander Pyhalov */
9816d86563SAlexander Pyhalov /*=======================================================
9916d86563SAlexander Pyhalov *
10016d86563SAlexander Pyhalov * State machine for interpreting ISO2022-CN-EXT code
10116d86563SAlexander Pyhalov *
10216d86563SAlexander Pyhalov *=======================================================
10316d86563SAlexander Pyhalov *
10416d86563SAlexander Pyhalov *
10516d86563SAlexander Pyhalov *=======================================================*/
10616d86563SAlexander Pyhalov
10716d86563SAlexander Pyhalov size_t
iso2022_icv_iconv(_iconv_st * st,char ** inbuf,size_t * inbytesleft,unsigned char ** outbuf,size_t * outbytesleft,int (* convert)())10816d86563SAlexander Pyhalov iso2022_icv_iconv(_iconv_st *st, char **inbuf, size_t *inbytesleft,
10916d86563SAlexander Pyhalov unsigned char **outbuf, size_t *outbytesleft, int (*convert)() )
11016d86563SAlexander Pyhalov {
11116d86563SAlexander Pyhalov
11216d86563SAlexander Pyhalov int ret, n;
11316d86563SAlexander Pyhalov
11416d86563SAlexander Pyhalov if (st == NULL) {
11516d86563SAlexander Pyhalov errno = EBADF;
11616d86563SAlexander Pyhalov return ((size_t) -1);
11716d86563SAlexander Pyhalov }
11816d86563SAlexander Pyhalov
11916d86563SAlexander Pyhalov if ( inbuf == NULL || *inbuf == NULL || inbytesleft == NULL ||
12016d86563SAlexander Pyhalov *inbytesleft <= 0 ) { /* Reset request */
12116d86563SAlexander Pyhalov st->Sfunc = SI;
12216d86563SAlexander Pyhalov st->SSfunc = NONE;
12316d86563SAlexander Pyhalov st->ESCstate = OFF;
12416d86563SAlexander Pyhalov st->firstbyte = True;
12516d86563SAlexander Pyhalov st->numsav = 0;
126*f642269fSToomas Soome st->SOcharset = 0;
127*f642269fSToomas Soome st->SS2charset = 0;
128*f642269fSToomas Soome st->SS3charset = 0;
12916d86563SAlexander Pyhalov st->nonidcount = 0;
13016d86563SAlexander Pyhalov st->_errno = 0;
13116d86563SAlexander Pyhalov return ((size_t) 0);
13216d86563SAlexander Pyhalov }
13316d86563SAlexander Pyhalov
13416d86563SAlexander Pyhalov st->_errno = 0;
13516d86563SAlexander Pyhalov errno = 0;
13616d86563SAlexander Pyhalov
13716d86563SAlexander Pyhalov /* Before we use *inbytesleft or *outbytesleft we should confirm that
13816d86563SAlexander Pyhalov inbytesleft and outbytesleft are non-NULL. I am considering inbytesleft
13916d86563SAlexander Pyhalov or *inbytesleft having 0 or negative value as a reset request. I am
14016d86563SAlexander Pyhalov considering outbytesleft having 0 value as no space in output buffer.
14116d86563SAlexander Pyhalov Also, here itself I am verifying that outbuf and *outbuf should be non-NULL
14216d86563SAlexander Pyhalov pointers so I do not have to worry about them being NULL below in the
14316d86563SAlexander Pyhalov conversion sub-routines. I also confirm here that *outbytesleft should be
14416d86563SAlexander Pyhalov greater than 0 before we can continue further */
14516d86563SAlexander Pyhalov
14616d86563SAlexander Pyhalov if ( outbytesleft == NULL || *outbytesleft <= 0 ||
14716d86563SAlexander Pyhalov outbuf == NULL || *outbuf == NULL ) {
14816d86563SAlexander Pyhalov errno = E2BIG;
14916d86563SAlexander Pyhalov return((size_t)-1);
15016d86563SAlexander Pyhalov }
15116d86563SAlexander Pyhalov
15216d86563SAlexander Pyhalov /* A state machine to interpret ISO, driven by the shift functions SI, SO */
15316d86563SAlexander Pyhalov
15416d86563SAlexander Pyhalov do {
15516d86563SAlexander Pyhalov if (st->firstbyte == False) { /* Is SO, SS2, SS3 second byte */
15616d86563SAlexander Pyhalov st->keepc[1] = **inbuf;
15716d86563SAlexander Pyhalov n = (*convert)( st, outbuf, outbytesleft, iscns(st) );
15816d86563SAlexander Pyhalov if ( n < 0 )
15916d86563SAlexander Pyhalov return((size_t)-1); /* Insufficient space in output buffer */
16016d86563SAlexander Pyhalov else if ( n > 0 ){ /* No CNS for this Chinese code */
16116d86563SAlexander Pyhalov n = ascii_to_euc(NON_ID_CHAR, st, outbuf, outbytesleft);
16216d86563SAlexander Pyhalov if ( n < 0 )
16316d86563SAlexander Pyhalov return((size_t)-1);
16416d86563SAlexander Pyhalov st->nonidcount += 1;
16516d86563SAlexander Pyhalov } else
16616d86563SAlexander Pyhalov st->nonidcount -= 1; /* The first byte identified as
16716d86563SAlexander Pyhalov valid Chinese byte and is
16816d86563SAlexander Pyhalov processed */
16916d86563SAlexander Pyhalov st->firstbyte = True;
17016d86563SAlexander Pyhalov st->SSfunc = NONE; /* If we just processed SS bytes,
17116d86563SAlexander Pyhalov this will reset SSfunc to NONE. If
17216d86563SAlexander Pyhalov we just processed SO bytes, this was
17316d86563SAlexander Pyhalov already NONE */
17416d86563SAlexander Pyhalov } else if ( st->SSfunc != NONE ) { /* We are currently expecting
17516d86563SAlexander Pyhalov SS2 or SS3 Chinese bytes */
17616d86563SAlexander Pyhalov st->keepc[0] = **inbuf;
17716d86563SAlexander Pyhalov st->nonidcount += 1;
17816d86563SAlexander Pyhalov st->firstbyte = False;
17916d86563SAlexander Pyhalov } else if ( **inbuf == ESC && st->ESCstate == OFF ) {
18016d86563SAlexander Pyhalov st->nonidcount += 1; /* For the ESC character */
18116d86563SAlexander Pyhalov st->ESCstate = E0;
18216d86563SAlexander Pyhalov } else if ( st->ESCstate != OFF ) { /* Continue processing the
18316d86563SAlexander Pyhalov escape sequence */
18416d86563SAlexander Pyhalov ret = process_esc_seq( **inbuf, st );
185*f642269fSToomas Soome if ( ret == DONE ) { /* ESC seq interpreted correctly.
18616d86563SAlexander Pyhalov Switch off the escape machine */
18716d86563SAlexander Pyhalov st->ESCstate = OFF;
18816d86563SAlexander Pyhalov } else if ( ret == INVALID ){
18916d86563SAlexander Pyhalov if (st->Sfunc == SI){ /* An invalid ESC sequence
19016d86563SAlexander Pyhalov encountered. Process
19116d86563SAlexander Pyhalov the text saved in
19216d86563SAlexander Pyhalov st->savbuf as ASCII. Switch
19316d86563SAlexander Pyhalov off the escape machine */
19416d86563SAlexander Pyhalov n = ascii_to_euc( **inbuf, st, outbuf, outbytesleft );
19516d86563SAlexander Pyhalov if ( n < 0 ) /* Insufficient space in output buffer */
19616d86563SAlexander Pyhalov return((size_t)-1);
19716d86563SAlexander Pyhalov st->nonidcount -= st->numsav; /* Since invalid Esc
19816d86563SAlexander Pyhalov sequence is outputted
19916d86563SAlexander Pyhalov as ASCII */
20016d86563SAlexander Pyhalov } else if (st->Sfunc == SO) { /* An invalid ESC sequence
20116d86563SAlexander Pyhalov encountered. Don't know
20216d86563SAlexander Pyhalov what to do. So flag
20316d86563SAlexander Pyhalov error illegal seq. It is
20416d86563SAlexander Pyhalov wise not to continue
20516d86563SAlexander Pyhalov processing input. Switch
20616d86563SAlexander Pyhalov off the escape machine */
20716d86563SAlexander Pyhalov st->_errno = errno = EILSEQ;
20816d86563SAlexander Pyhalov st->nonidcount += 1; /* For this character */
20916d86563SAlexander Pyhalov }
210*f642269fSToomas Soome st->numsav = 0; /* Discard the saved characters of
21116d86563SAlexander Pyhalov invalid sequence */
21216d86563SAlexander Pyhalov st->ESCstate = OFF;
21316d86563SAlexander Pyhalov } /* more char. needed for escape sequence */
21416d86563SAlexander Pyhalov } else if (st->Sfunc == SI) {
21516d86563SAlexander Pyhalov /* Switch state to SO only if SOdesignation is set. */
216*f642269fSToomas Soome if ( **inbuf == SO && st->SOcharset != 0 ){
21716d86563SAlexander Pyhalov st->Sfunc = SO;
21816d86563SAlexander Pyhalov } else { /* Is ASCII */
21916d86563SAlexander Pyhalov n = ascii_to_euc(**inbuf, st, outbuf, outbytesleft );
22016d86563SAlexander Pyhalov if ( n < 0 ) /* Insufficient space in output buffer */
22116d86563SAlexander Pyhalov return((size_t)-1);
22216d86563SAlexander Pyhalov }
22316d86563SAlexander Pyhalov } else if (st->Sfunc == SO) {
22416d86563SAlexander Pyhalov if ( **inbuf == SI ){ /* Switch state to SO */
22516d86563SAlexander Pyhalov st->Sfunc = SI;
22616d86563SAlexander Pyhalov }
22716d86563SAlexander Pyhalov else {
22816d86563SAlexander Pyhalov st->keepc[0] = **inbuf;
22916d86563SAlexander Pyhalov st->nonidcount += 1;
23016d86563SAlexander Pyhalov st->firstbyte = False;
23116d86563SAlexander Pyhalov }
23216d86563SAlexander Pyhalov }
23316d86563SAlexander Pyhalov else
23416d86563SAlexander Pyhalov fprintf(stderr,
23516d86563SAlexander Pyhalov "_icv_iconv():ISO-CN-EXT->CNS:Should never have come here\n");
23616d86563SAlexander Pyhalov
23716d86563SAlexander Pyhalov (*inbuf)++;
23816d86563SAlexander Pyhalov (*inbytesleft)--;
23916d86563SAlexander Pyhalov
24016d86563SAlexander Pyhalov if ( st->_errno)
24116d86563SAlexander Pyhalov break; /* Break out of while loop */
24216d86563SAlexander Pyhalov
24316d86563SAlexander Pyhalov if (errno) /* We set st->_errno before we set errno. If errno is set
24416d86563SAlexander Pyhalov somewhere else we handle that here */
24516d86563SAlexander Pyhalov return((size_t)-1);
24616d86563SAlexander Pyhalov
24716d86563SAlexander Pyhalov } while (*inbytesleft > 0 && *outbytesleft > 0);
24816d86563SAlexander Pyhalov
24916d86563SAlexander Pyhalov
25016d86563SAlexander Pyhalov /* We now have to handle the case where we have successfully processed the
25116d86563SAlexander Pyhalov previous input character which exhausted the output buffer. This is handled
25216d86563SAlexander Pyhalov by the while loop. However, since there are more input characters that
25316d86563SAlexander Pyhalov haven't been processed yet, we need to set the errno appropriately and
25416d86563SAlexander Pyhalov return -1. */
25516d86563SAlexander Pyhalov if ( *inbytesleft > 0 && *outbytesleft == 0) {
25616d86563SAlexander Pyhalov errno = E2BIG;
25716d86563SAlexander Pyhalov return((size_t)-1);
25816d86563SAlexander Pyhalov }
25916d86563SAlexander Pyhalov return (*inbytesleft + st->nonidcount);
26016d86563SAlexander Pyhalov }
26116d86563SAlexander Pyhalov
26216d86563SAlexander Pyhalov
26316d86563SAlexander Pyhalov static int
process_esc_seq(char c,_iconv_st * st)26416d86563SAlexander Pyhalov process_esc_seq( char c, _iconv_st *st )
26516d86563SAlexander Pyhalov {
26616d86563SAlexander Pyhalov
26716d86563SAlexander Pyhalov switch(st->ESCstate){
26816d86563SAlexander Pyhalov case E0:
26916d86563SAlexander Pyhalov switch (c){
27016d86563SAlexander Pyhalov case SS2LOW:
271*f642269fSToomas Soome if ( st->SS2charset == 0 ){
27216d86563SAlexander Pyhalov /* We do not expect SS2 shift function before
27316d86563SAlexander Pyhalov SS2 designation is set */
27416d86563SAlexander Pyhalov st->savbuf[0] = ESC;
27516d86563SAlexander Pyhalov st->numsav = 1;
27616d86563SAlexander Pyhalov return(INVALID);
27716d86563SAlexander Pyhalov }
27816d86563SAlexander Pyhalov st->SSfunc = SS2;
27916d86563SAlexander Pyhalov /* Since valid ESC sequence remove the ESC from the
28016d86563SAlexander Pyhalov nonidcount */
28116d86563SAlexander Pyhalov st->nonidcount -= 1;
28216d86563SAlexander Pyhalov return(DONE);
28316d86563SAlexander Pyhalov case SS3LOW:
284*f642269fSToomas Soome if ( st->SS3charset == 0 ){
28516d86563SAlexander Pyhalov /* We do not expect SS3 shift function before
28616d86563SAlexander Pyhalov SS3 designation is set */
28716d86563SAlexander Pyhalov st->savbuf[0] = ESC;
28816d86563SAlexander Pyhalov st->numsav = 1;
28916d86563SAlexander Pyhalov return(INVALID);
29016d86563SAlexander Pyhalov }
29116d86563SAlexander Pyhalov st->SSfunc = SS3;
29216d86563SAlexander Pyhalov /* Since valid ESC sequence remove the ESC from the
29316d86563SAlexander Pyhalov nonidcount */
29416d86563SAlexander Pyhalov st->nonidcount -= 1;
29516d86563SAlexander Pyhalov return(DONE);
29616d86563SAlexander Pyhalov case '$':
29716d86563SAlexander Pyhalov st->nonidcount += 1; /* ESC sequence not complete yet */
29816d86563SAlexander Pyhalov st->ESCstate = E1;
29916d86563SAlexander Pyhalov return(NEEDMORE);
30016d86563SAlexander Pyhalov default:
30116d86563SAlexander Pyhalov st->savbuf[0] = ESC;
30216d86563SAlexander Pyhalov st->numsav = 1;
30316d86563SAlexander Pyhalov return(INVALID);
30416d86563SAlexander Pyhalov } /* end switch */
30516d86563SAlexander Pyhalov
30616d86563SAlexander Pyhalov
30716d86563SAlexander Pyhalov case E1:
30816d86563SAlexander Pyhalov switch (c){
30916d86563SAlexander Pyhalov case ')':
31016d86563SAlexander Pyhalov st->nonidcount += 1; /* ESC sequence not complete yet */
31116d86563SAlexander Pyhalov st->ESCstate = E2;
31216d86563SAlexander Pyhalov return(NEEDMORE);
31316d86563SAlexander Pyhalov case '*':
31416d86563SAlexander Pyhalov st->nonidcount += 1; /* ESC sequence not complete yet */
31516d86563SAlexander Pyhalov st->ESCstate = E3;
31616d86563SAlexander Pyhalov return(NEEDMORE);
31716d86563SAlexander Pyhalov case '+':
31816d86563SAlexander Pyhalov st->nonidcount += 1; /* ESC sequence not complete yet */
31916d86563SAlexander Pyhalov st->ESCstate = E4;
32016d86563SAlexander Pyhalov return(NEEDMORE);
32116d86563SAlexander Pyhalov default:
32216d86563SAlexander Pyhalov st->savbuf[0] = ESC;
32316d86563SAlexander Pyhalov st->savbuf[1] = '$';
32416d86563SAlexander Pyhalov st->numsav = 2;
32516d86563SAlexander Pyhalov return(INVALID);
32616d86563SAlexander Pyhalov }
32716d86563SAlexander Pyhalov
32816d86563SAlexander Pyhalov case E2:
32916d86563SAlexander Pyhalov st->SOcharset = c;
33016d86563SAlexander Pyhalov /* Since valid ESC sequence remove decriment nonidcount
33116d86563SAlexander Pyhalov appropriately for all earlier characters in escape sequence */
33216d86563SAlexander Pyhalov st->nonidcount -= 3;
33316d86563SAlexander Pyhalov return(DONE);
33416d86563SAlexander Pyhalov
33516d86563SAlexander Pyhalov case E3:
33616d86563SAlexander Pyhalov st->SS2charset = c;
33716d86563SAlexander Pyhalov /* Since valid ESC sequence remove decriment nonidcount
33816d86563SAlexander Pyhalov appropriately for all earlier characters in escape sequence */
33916d86563SAlexander Pyhalov st->nonidcount -= 3;
34016d86563SAlexander Pyhalov return(DONE);
34116d86563SAlexander Pyhalov
34216d86563SAlexander Pyhalov case E4:
34316d86563SAlexander Pyhalov st->SS3charset = c;
34416d86563SAlexander Pyhalov /* Since valid ESC sequence remove decriment nonidcount
34516d86563SAlexander Pyhalov appropriately for all earlier characters in escape sequence */
34616d86563SAlexander Pyhalov st->nonidcount -= 3;
34716d86563SAlexander Pyhalov return(DONE);
34816d86563SAlexander Pyhalov
34916d86563SAlexander Pyhalov default:
35016d86563SAlexander Pyhalov fprintf(stderr,
35116d86563SAlexander Pyhalov "process_esc_seq():ISO-CN-EXT->CNS:Should never have come here\n");
35216d86563SAlexander Pyhalov st->_errno = errno = EILSEQ;
35316d86563SAlexander Pyhalov return(DONE);
35416d86563SAlexander Pyhalov
35516d86563SAlexander Pyhalov } /* end switch */
35616d86563SAlexander Pyhalov }
35716d86563SAlexander Pyhalov
35816d86563SAlexander Pyhalov
35916d86563SAlexander Pyhalov static int
ascii_to_euc(char c,_iconv_st * st,unsigned char ** outbuf,size_t * outbytesleft)36016d86563SAlexander Pyhalov ascii_to_euc( char c, _iconv_st *st, unsigned char **outbuf, size_t *outbytesleft )
36116d86563SAlexander Pyhalov {
36216d86563SAlexander Pyhalov
36316d86563SAlexander Pyhalov int i;
36416d86563SAlexander Pyhalov
36516d86563SAlexander Pyhalov if ( *outbytesleft < (1 + st->numsav) ) {
36616d86563SAlexander Pyhalov st->_errno = errno = E2BIG;
36716d86563SAlexander Pyhalov return (-1);
36816d86563SAlexander Pyhalov }
36916d86563SAlexander Pyhalov
37016d86563SAlexander Pyhalov for ( i=0; i < st->numsav; i++ ) {
37116d86563SAlexander Pyhalov *(*outbuf)++ = (unsigned char) st->savbuf[i];
37216d86563SAlexander Pyhalov (*outbytesleft)--;
37316d86563SAlexander Pyhalov }
37416d86563SAlexander Pyhalov
37516d86563SAlexander Pyhalov *(*outbuf)++ = (unsigned char) c;
37616d86563SAlexander Pyhalov (*outbytesleft)--;
37716d86563SAlexander Pyhalov
37816d86563SAlexander Pyhalov return(0);
37916d86563SAlexander Pyhalov }
38016d86563SAlexander Pyhalov
38116d86563SAlexander Pyhalov
38216d86563SAlexander Pyhalov static int
iscns(_iconv_st * st)38316d86563SAlexander Pyhalov iscns( _iconv_st *st )
38416d86563SAlexander Pyhalov {
38516d86563SAlexander Pyhalov int plane_no = -1;
38616d86563SAlexander Pyhalov
387*f642269fSToomas Soome if ( st->SSfunc == NONE && st->SOcharset == 'G' )
38816d86563SAlexander Pyhalov plane_no = 1;
38916d86563SAlexander Pyhalov else if ( st->SSfunc == SS2 && st->SS2charset == 'H' )
39016d86563SAlexander Pyhalov plane_no = 2;
39116d86563SAlexander Pyhalov else if ( st->SSfunc == SS3 )
39216d86563SAlexander Pyhalov switch ( st->SS3charset ){
39316d86563SAlexander Pyhalov case 'I': plane_no = 3; break;
39416d86563SAlexander Pyhalov case 'J': plane_no = 4; break;
39516d86563SAlexander Pyhalov case 'K': plane_no = 5; break;
39616d86563SAlexander Pyhalov case 'L': plane_no = 6; break;
39716d86563SAlexander Pyhalov case 'M': plane_no = 7; break;
39816d86563SAlexander Pyhalov }
39916d86563SAlexander Pyhalov return (plane_no);
40016d86563SAlexander Pyhalov }
401