xref: /titanic_51/usr/src/lib/iconv_modules/hi_IN/iscii91%ea-iscii.c (revision 91e1e26ac6a73ce959289cf7d3d96c4baedbe0b8)
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) 2001 Sun Microsystems, Inc.
23*91e1e26aSAlexander Pyhalov  * All rights reserved.
24*91e1e26aSAlexander Pyhalov  */
25*91e1e26aSAlexander Pyhalov #include <stdio.h>
26*91e1e26aSAlexander Pyhalov #include <errno.h>
27*91e1e26aSAlexander Pyhalov #include <ctype.h>
28*91e1e26aSAlexander Pyhalov #include <strings.h>
29*91e1e26aSAlexander Pyhalov #include <stdlib.h>
30*91e1e26aSAlexander Pyhalov #include "ea-iscii.h"
31*91e1e26aSAlexander Pyhalov 
32*91e1e26aSAlexander Pyhalov #define MSB          0x80
33*91e1e26aSAlexander Pyhalov #define REPLACE_CHAR '?'
34*91e1e26aSAlexander Pyhalov 
35*91e1e26aSAlexander Pyhalov typedef enum { SPACE, ASCII, ISCII } CONTEXT;
36*91e1e26aSAlexander Pyhalov 
37*91e1e26aSAlexander Pyhalov typedef struct _icv_state {
38*91e1e26aSAlexander Pyhalov     CONTEXT context;
39*91e1e26aSAlexander Pyhalov } _iconv_st;
40*91e1e26aSAlexander Pyhalov 
41*91e1e26aSAlexander Pyhalov static uchar
42*91e1e26aSAlexander Pyhalov traverse_table(Entry *entry , int num, uchar iscii, uchar *type)
43*91e1e26aSAlexander Pyhalov {
44*91e1e26aSAlexander Pyhalov     int   i = 0;
45*91e1e26aSAlexander Pyhalov     uchar ea_iscii=0;
46*91e1e26aSAlexander Pyhalov 
47*91e1e26aSAlexander Pyhalov     *type = 0;
48*91e1e26aSAlexander Pyhalov 
49*91e1e26aSAlexander Pyhalov     for ( ; i < num; ++i) {
50*91e1e26aSAlexander Pyhalov         Entry en = entry[i];
51*91e1e26aSAlexander Pyhalov 
52*91e1e26aSAlexander Pyhalov 	if ( iscii < en.iscii ) break;
53*91e1e26aSAlexander Pyhalov 
54*91e1e26aSAlexander Pyhalov         if ( en.count == NUKTA || en.count == MATRA || en.count ==
55*91e1e26aSAlexander Pyhalov              COMBINED_MATRA_NUKTA ) {
56*91e1e26aSAlexander Pyhalov 	     if ( iscii == en.iscii ) {
57*91e1e26aSAlexander Pyhalov                  *type = en.count;
58*91e1e26aSAlexander Pyhalov                  ea_iscii = en.ea_iscii;
59*91e1e26aSAlexander Pyhalov                  break;
60*91e1e26aSAlexander Pyhalov              }
61*91e1e26aSAlexander Pyhalov         } else {
62*91e1e26aSAlexander Pyhalov              if ( iscii >= en.iscii && iscii < en.iscii + en.count ) {
63*91e1e26aSAlexander Pyhalov                  ea_iscii = (iscii - en.iscii) + en.ea_iscii;
64*91e1e26aSAlexander Pyhalov                  break;
65*91e1e26aSAlexander Pyhalov              }
66*91e1e26aSAlexander Pyhalov         }
67*91e1e26aSAlexander Pyhalov     }
68*91e1e26aSAlexander Pyhalov 
69*91e1e26aSAlexander Pyhalov     return ea_iscii;
70*91e1e26aSAlexander Pyhalov }
71*91e1e26aSAlexander Pyhalov 
72*91e1e26aSAlexander Pyhalov void *
73*91e1e26aSAlexander Pyhalov _icv_open()
74*91e1e26aSAlexander Pyhalov {
75*91e1e26aSAlexander Pyhalov     _iconv_st *st;
76*91e1e26aSAlexander Pyhalov 
77*91e1e26aSAlexander Pyhalov     if ((st = (_iconv_st*)malloc(sizeof(_iconv_st))) == NULL) {
78*91e1e26aSAlexander Pyhalov         errno = ENOMEM;
79*91e1e26aSAlexander Pyhalov         return ((void*)-1);
80*91e1e26aSAlexander Pyhalov     }
81*91e1e26aSAlexander Pyhalov 
82*91e1e26aSAlexander Pyhalov     bzero(st, sizeof(_iconv_st));
83*91e1e26aSAlexander Pyhalov 
84*91e1e26aSAlexander Pyhalov     return ((void*)st);
85*91e1e26aSAlexander Pyhalov }
86*91e1e26aSAlexander Pyhalov 
87*91e1e26aSAlexander Pyhalov /*
88*91e1e26aSAlexander Pyhalov  * Close; called from iconv_close()
89*91e1e26aSAlexander Pyhalov  */
90*91e1e26aSAlexander Pyhalov void
91*91e1e26aSAlexander Pyhalov _icv_close(_iconv_st *st)
92*91e1e26aSAlexander Pyhalov {
93*91e1e26aSAlexander Pyhalov     if (!st)
94*91e1e26aSAlexander Pyhalov         errno = EBADF;
95*91e1e26aSAlexander Pyhalov     else
96*91e1e26aSAlexander Pyhalov         free(st);
97*91e1e26aSAlexander Pyhalov }
98*91e1e26aSAlexander Pyhalov 
99*91e1e26aSAlexander Pyhalov size_t
100*91e1e26aSAlexander Pyhalov _icv_iconv(_iconv_st *st, char **inbuf, size_t *inbytesleft,
101*91e1e26aSAlexander Pyhalov        char **outbuf, size_t *outbytesleft)
102*91e1e26aSAlexander Pyhalov {
103*91e1e26aSAlexander Pyhalov     if (st == NULL) {
104*91e1e26aSAlexander Pyhalov         errno = EBADF;
105*91e1e26aSAlexander Pyhalov         return ((size_t) -1);
106*91e1e26aSAlexander Pyhalov     }
107*91e1e26aSAlexander Pyhalov 
108*91e1e26aSAlexander Pyhalov     if (inbuf == NULL || *inbuf == NULL) { /* Reset request. */
109*91e1e26aSAlexander Pyhalov         return ((size_t)0);
110*91e1e26aSAlexander Pyhalov     }
111*91e1e26aSAlexander Pyhalov 
112*91e1e26aSAlexander Pyhalov     /* a state machine for interpreting ISCII code */
113*91e1e26aSAlexander Pyhalov     while (*inbytesleft > 0 && *outbytesleft > 0) {
114*91e1e26aSAlexander Pyhalov         uchar c = (uchar)**inbuf;
115*91e1e26aSAlexander Pyhalov 
116*91e1e26aSAlexander Pyhalov         if ( c & MSB ) {
117*91e1e26aSAlexander Pyhalov 
118*91e1e26aSAlexander Pyhalov              uchar type, ea_iscii;
119*91e1e26aSAlexander Pyhalov 
120*91e1e26aSAlexander Pyhalov              if ( st->context != ISCII ) {
121*91e1e26aSAlexander Pyhalov 
122*91e1e26aSAlexander Pyhalov                  if ( st->context != SPACE ) {
123*91e1e26aSAlexander Pyhalov                     /* force to insert ' ' between ASCII and ISCII */
124*91e1e26aSAlexander Pyhalov                     **outbuf = 0x20;
125*91e1e26aSAlexander Pyhalov                     (*outbuf)++;
126*91e1e26aSAlexander Pyhalov                     (*outbytesleft)--;
127*91e1e26aSAlexander Pyhalov                     st->context = SPACE;
128*91e1e26aSAlexander Pyhalov                  }
129*91e1e26aSAlexander Pyhalov 
130*91e1e26aSAlexander Pyhalov                  if ( *outbytesleft < 1 ) {
131*91e1e26aSAlexander Pyhalov                      errno = E2BIG;
132*91e1e26aSAlexander Pyhalov                      /* don't advance */
133*91e1e26aSAlexander Pyhalov                      return (size_t)-1;
134*91e1e26aSAlexander Pyhalov                  }
135*91e1e26aSAlexander Pyhalov 
136*91e1e26aSAlexander Pyhalov                  st->context = ISCII;
137*91e1e26aSAlexander Pyhalov                  **outbuf = LEADING_BYTE;
138*91e1e26aSAlexander Pyhalov                  (*outbuf)++;
139*91e1e26aSAlexander Pyhalov                  (*outbytesleft)--;
140*91e1e26aSAlexander Pyhalov              }
141*91e1e26aSAlexander Pyhalov 
142*91e1e26aSAlexander Pyhalov              if ((ea_iscii = traverse_table(isc_eaiscii_tbl,
143*91e1e26aSAlexander Pyhalov 			sizeof(isc_eaiscii_tbl)/sizeof(Entry), c, &type ))) {
144*91e1e26aSAlexander Pyhalov                  switch ( type ) {
145*91e1e26aSAlexander Pyhalov                  case MATRA:
146*91e1e26aSAlexander Pyhalov                       if ( *outbytesleft < 2 ) {
147*91e1e26aSAlexander Pyhalov                          errno = E2BIG;
148*91e1e26aSAlexander Pyhalov                          return (size_t)-1;
149*91e1e26aSAlexander Pyhalov                       }
150*91e1e26aSAlexander Pyhalov 
151*91e1e26aSAlexander Pyhalov                       **outbuf = FIRST_VOWEL;
152*91e1e26aSAlexander Pyhalov                       *(*outbuf+1) = ea_iscii;
153*91e1e26aSAlexander Pyhalov                       (*outbuf) += 2;
154*91e1e26aSAlexander Pyhalov                       (*outbytesleft) -= 2;
155*91e1e26aSAlexander Pyhalov                       break;
156*91e1e26aSAlexander Pyhalov                  case NUKTA:
157*91e1e26aSAlexander Pyhalov                       if ( *outbytesleft < 2 ) {
158*91e1e26aSAlexander Pyhalov                          errno = E2BIG;
159*91e1e26aSAlexander Pyhalov                          return (size_t)-1;
160*91e1e26aSAlexander Pyhalov                       }
161*91e1e26aSAlexander Pyhalov 
162*91e1e26aSAlexander Pyhalov                       **outbuf = ea_iscii;
163*91e1e26aSAlexander Pyhalov                       *(*outbuf+1) = NUKTA_VALUE;
164*91e1e26aSAlexander Pyhalov                       (*outbuf) += 2;
165*91e1e26aSAlexander Pyhalov                       (*outbytesleft) -= 2;
166*91e1e26aSAlexander Pyhalov                       break;
167*91e1e26aSAlexander Pyhalov                  case COMBINED_MATRA_NUKTA:
168*91e1e26aSAlexander Pyhalov                       if ( *outbytesleft < 3 ) {
169*91e1e26aSAlexander Pyhalov                          errno = E2BIG;
170*91e1e26aSAlexander Pyhalov                          return (size_t)-1;
171*91e1e26aSAlexander Pyhalov                       }
172*91e1e26aSAlexander Pyhalov 
173*91e1e26aSAlexander Pyhalov                       **outbuf = FIRST_VOWEL;
174*91e1e26aSAlexander Pyhalov                       *(*outbuf+1) = ea_iscii;
175*91e1e26aSAlexander Pyhalov                       *(*outbuf+2) = NUKTA_VALUE;
176*91e1e26aSAlexander Pyhalov                       (*outbuf) += 3;
177*91e1e26aSAlexander Pyhalov                       (*outbytesleft) -= 3;
178*91e1e26aSAlexander Pyhalov                       break;
179*91e1e26aSAlexander Pyhalov                  case 0:
180*91e1e26aSAlexander Pyhalov                       if ( *outbytesleft < 1 ) {
181*91e1e26aSAlexander Pyhalov                          errno = E2BIG;
182*91e1e26aSAlexander Pyhalov                          return (size_t)-1;
183*91e1e26aSAlexander Pyhalov                       }
184*91e1e26aSAlexander Pyhalov 
185*91e1e26aSAlexander Pyhalov                       **outbuf = ea_iscii;
186*91e1e26aSAlexander Pyhalov                       (*outbuf)++;
187*91e1e26aSAlexander Pyhalov                       (*outbytesleft)--;
188*91e1e26aSAlexander Pyhalov                       break;
189*91e1e26aSAlexander Pyhalov                  }
190*91e1e26aSAlexander Pyhalov              } else { /* REPLACE_CHAR */
191*91e1e26aSAlexander Pyhalov                  if ( *outbytesleft < 1 ) {
192*91e1e26aSAlexander Pyhalov                     errno = E2BIG;
193*91e1e26aSAlexander Pyhalov                     return (size_t)-1;
194*91e1e26aSAlexander Pyhalov                  }
195*91e1e26aSAlexander Pyhalov 
196*91e1e26aSAlexander Pyhalov                  **outbuf = REPLACE_CHAR;
197*91e1e26aSAlexander Pyhalov                  (*outbuf)++;
198*91e1e26aSAlexander Pyhalov                  (*outbytesleft)--;
199*91e1e26aSAlexander Pyhalov              }
200*91e1e26aSAlexander Pyhalov         } else { /* ASCII */
201*91e1e26aSAlexander Pyhalov              if ( st->context == ISCII && !isspace(c) ) {
202*91e1e26aSAlexander Pyhalov                  /* force to insert ' ' between ASCII and ISCII */
203*91e1e26aSAlexander Pyhalov                  **outbuf = 0x20;
204*91e1e26aSAlexander Pyhalov                  (*outbuf)++;
205*91e1e26aSAlexander Pyhalov                  (*outbytesleft)--;
206*91e1e26aSAlexander Pyhalov                  st->context = SPACE;
207*91e1e26aSAlexander Pyhalov              }
208*91e1e26aSAlexander Pyhalov 
209*91e1e26aSAlexander Pyhalov              if ( *outbytesleft < 1 ) {
210*91e1e26aSAlexander Pyhalov                 errno = E2BIG;
211*91e1e26aSAlexander Pyhalov                 return (size_t)-1;
212*91e1e26aSAlexander Pyhalov              }
213*91e1e26aSAlexander Pyhalov 
214*91e1e26aSAlexander Pyhalov              **outbuf = c;
215*91e1e26aSAlexander Pyhalov              (*outbuf)++;
216*91e1e26aSAlexander Pyhalov              (*outbytesleft)--;
217*91e1e26aSAlexander Pyhalov 
218*91e1e26aSAlexander Pyhalov              st->context = ASCII;
219*91e1e26aSAlexander Pyhalov              if ( isspace(c) )
220*91e1e26aSAlexander Pyhalov                   st->context = SPACE;
221*91e1e26aSAlexander Pyhalov         }
222*91e1e26aSAlexander Pyhalov 
223*91e1e26aSAlexander Pyhalov         (*inbuf)++;
224*91e1e26aSAlexander Pyhalov         (*inbytesleft)--;
225*91e1e26aSAlexander Pyhalov     }
226*91e1e26aSAlexander Pyhalov 
227*91e1e26aSAlexander Pyhalov     if ( *inbytesleft > 0 && *outbytesleft == 0 ) {
228*91e1e26aSAlexander Pyhalov          errno = E2BIG;
229*91e1e26aSAlexander Pyhalov          return ((size_t)-1);
230*91e1e26aSAlexander Pyhalov     }
231*91e1e26aSAlexander Pyhalov 
232*91e1e26aSAlexander Pyhalov     return ((size_t)(*inbytesleft));
233*91e1e26aSAlexander Pyhalov }
234