1*7c568831SAndroid Build Coastguard Worker /**
2*7c568831SAndroid Build Coastguard Worker *** iconv_open(), iconv(), iconv_close() wrappers for the OS/400.
3*7c568831SAndroid Build Coastguard Worker ***
4*7c568831SAndroid Build Coastguard Worker *** See Copyright for the status of this software.
5*7c568831SAndroid Build Coastguard Worker ***
6*7c568831SAndroid Build Coastguard Worker *** Author: Patrick Monnerat <[email protected]>, DATASPHERE S.A.
7*7c568831SAndroid Build Coastguard Worker **/
8*7c568831SAndroid Build Coastguard Worker
9*7c568831SAndroid Build Coastguard Worker #include <errno.h>
10*7c568831SAndroid Build Coastguard Worker #include <stdio.h>
11*7c568831SAndroid Build Coastguard Worker #include <stdlib.h>
12*7c568831SAndroid Build Coastguard Worker
13*7c568831SAndroid Build Coastguard Worker #include "/QIBM/include/iconv.h" /* Force system definition. */
14*7c568831SAndroid Build Coastguard Worker
15*7c568831SAndroid Build Coastguard Worker #define USE_SYSTEM_ICONV
16*7c568831SAndroid Build Coastguard Worker #include "iconv.h" /* Use local definitions. */
17*7c568831SAndroid Build Coastguard Worker
18*7c568831SAndroid Build Coastguard Worker
19*7c568831SAndroid Build Coastguard Worker
20*7c568831SAndroid Build Coastguard Worker /**
21*7c568831SAndroid Build Coastguard Worker *** Bring-in the name-->CCSID mapping DFA tables.
22*7c568831SAndroid Build Coastguard Worker **/
23*7c568831SAndroid Build Coastguard Worker
24*7c568831SAndroid Build Coastguard Worker #include "ianatables.c"
25*7c568831SAndroid Build Coastguard Worker
26*7c568831SAndroid Build Coastguard Worker
27*7c568831SAndroid Build Coastguard Worker
28*7c568831SAndroid Build Coastguard Worker static int
findEncoding(const unsigned char ** namep)29*7c568831SAndroid Build Coastguard Worker findEncoding(const unsigned char * * namep)
30*7c568831SAndroid Build Coastguard Worker
31*7c568831SAndroid Build Coastguard Worker {
32*7c568831SAndroid Build Coastguard Worker t_staterange curstate;
33*7c568831SAndroid Build Coastguard Worker t_ccsid ccsid;
34*7c568831SAndroid Build Coastguard Worker t_ccsid final;
35*7c568831SAndroid Build Coastguard Worker t_transrange l;
36*7c568831SAndroid Build Coastguard Worker t_transrange h;
37*7c568831SAndroid Build Coastguard Worker const unsigned char * name;
38*7c568831SAndroid Build Coastguard Worker
39*7c568831SAndroid Build Coastguard Worker /**
40*7c568831SAndroid Build Coastguard Worker *** Get the CCSID correspong to the name at *`namep'.
41*7c568831SAndroid Build Coastguard Worker *** If success, update pointer at `namep' to 1st byte after matched
42*7c568831SAndroid Build Coastguard Worker *** name and return the CCSID.
43*7c568831SAndroid Build Coastguard Worker *** If failure, set errno and return -1.
44*7c568831SAndroid Build Coastguard Worker **/
45*7c568831SAndroid Build Coastguard Worker
46*7c568831SAndroid Build Coastguard Worker if (!namep || !(name = *namep)) {
47*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
48*7c568831SAndroid Build Coastguard Worker return -1;
49*7c568831SAndroid Build Coastguard Worker }
50*7c568831SAndroid Build Coastguard Worker
51*7c568831SAndroid Build Coastguard Worker curstate = 0;
52*7c568831SAndroid Build Coastguard Worker final = 0;
53*7c568831SAndroid Build Coastguard Worker
54*7c568831SAndroid Build Coastguard Worker for (;;) {
55*7c568831SAndroid Build Coastguard Worker if (curstate < sizeof final_array / sizeof final_array[0])
56*7c568831SAndroid Build Coastguard Worker if (final_array[curstate]) {
57*7c568831SAndroid Build Coastguard Worker final = final_array[curstate];
58*7c568831SAndroid Build Coastguard Worker *namep = name;
59*7c568831SAndroid Build Coastguard Worker }
60*7c568831SAndroid Build Coastguard Worker
61*7c568831SAndroid Build Coastguard Worker l = trans_array[curstate] - 1;
62*7c568831SAndroid Build Coastguard Worker h = trans_array[curstate + 1];
63*7c568831SAndroid Build Coastguard Worker
64*7c568831SAndroid Build Coastguard Worker do {
65*7c568831SAndroid Build Coastguard Worker if (++l >= h) {
66*7c568831SAndroid Build Coastguard Worker if (!final) {
67*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
68*7c568831SAndroid Build Coastguard Worker return -1;
69*7c568831SAndroid Build Coastguard Worker }
70*7c568831SAndroid Build Coastguard Worker
71*7c568831SAndroid Build Coastguard Worker return final - 1;
72*7c568831SAndroid Build Coastguard Worker }
73*7c568831SAndroid Build Coastguard Worker } while (label_array[l] != *name);
74*7c568831SAndroid Build Coastguard Worker
75*7c568831SAndroid Build Coastguard Worker curstate = goto_array[l];
76*7c568831SAndroid Build Coastguard Worker name++;
77*7c568831SAndroid Build Coastguard Worker }
78*7c568831SAndroid Build Coastguard Worker
79*7c568831SAndroid Build Coastguard Worker /* NOTREACHED. */
80*7c568831SAndroid Build Coastguard Worker }
81*7c568831SAndroid Build Coastguard Worker
82*7c568831SAndroid Build Coastguard Worker
83*7c568831SAndroid Build Coastguard Worker static void
makeos400codename(char * buf,unsigned int ccsid)84*7c568831SAndroid Build Coastguard Worker makeos400codename(char * buf, unsigned int ccsid)
85*7c568831SAndroid Build Coastguard Worker
86*7c568831SAndroid Build Coastguard Worker {
87*7c568831SAndroid Build Coastguard Worker ccsid &= 0xFFFF;
88*7c568831SAndroid Build Coastguard Worker memset(buf, 0, 32);
89*7c568831SAndroid Build Coastguard Worker sprintf(buf, "IBMCCSID%05u0000000", ccsid);
90*7c568831SAndroid Build Coastguard Worker }
91*7c568831SAndroid Build Coastguard Worker
92*7c568831SAndroid Build Coastguard Worker
93*7c568831SAndroid Build Coastguard Worker Iconv_t
IconvOpen(const char * tocode,const char * fromcode)94*7c568831SAndroid Build Coastguard Worker IconvOpen(const char * tocode, const char * fromcode)
95*7c568831SAndroid Build Coastguard Worker
96*7c568831SAndroid Build Coastguard Worker {
97*7c568831SAndroid Build Coastguard Worker int toccsid = findEncoding(&tocode);
98*7c568831SAndroid Build Coastguard Worker int fromccsid = findEncoding(&fromcode);
99*7c568831SAndroid Build Coastguard Worker char fromibmccsid[33];
100*7c568831SAndroid Build Coastguard Worker char toibmccsid[33];
101*7c568831SAndroid Build Coastguard Worker iconv_t * cd;
102*7c568831SAndroid Build Coastguard Worker
103*7c568831SAndroid Build Coastguard Worker if (toccsid < 0 || fromccsid < 0)
104*7c568831SAndroid Build Coastguard Worker return (Iconv_t) -1;
105*7c568831SAndroid Build Coastguard Worker
106*7c568831SAndroid Build Coastguard Worker makeos400codename(fromibmccsid, fromccsid);
107*7c568831SAndroid Build Coastguard Worker makeos400codename(toibmccsid, toccsid);
108*7c568831SAndroid Build Coastguard Worker memset(toibmccsid + 13, 0, sizeof toibmccsid - 13);
109*7c568831SAndroid Build Coastguard Worker
110*7c568831SAndroid Build Coastguard Worker cd = (iconv_t *) malloc(sizeof *cd);
111*7c568831SAndroid Build Coastguard Worker
112*7c568831SAndroid Build Coastguard Worker if (!cd)
113*7c568831SAndroid Build Coastguard Worker return (Iconv_t) -1;
114*7c568831SAndroid Build Coastguard Worker
115*7c568831SAndroid Build Coastguard Worker *cd = iconv_open(toibmccsid, fromibmccsid);
116*7c568831SAndroid Build Coastguard Worker
117*7c568831SAndroid Build Coastguard Worker if (cd->return_value) {
118*7c568831SAndroid Build Coastguard Worker free((char *) cd);
119*7c568831SAndroid Build Coastguard Worker return (Iconv_t) -1;
120*7c568831SAndroid Build Coastguard Worker }
121*7c568831SAndroid Build Coastguard Worker
122*7c568831SAndroid Build Coastguard Worker return (Iconv_t) cd;
123*7c568831SAndroid Build Coastguard Worker }
124*7c568831SAndroid Build Coastguard Worker
125*7c568831SAndroid Build Coastguard Worker
126*7c568831SAndroid Build Coastguard Worker size_t
Iconv(Iconv_t cd,char ** inbuf,size_t * inbytesleft,char ** outbuf,size_t * outbytesleft)127*7c568831SAndroid Build Coastguard Worker Iconv(Iconv_t cd, char * * inbuf, size_t * inbytesleft,
128*7c568831SAndroid Build Coastguard Worker char * * outbuf, size_t * outbytesleft)
129*7c568831SAndroid Build Coastguard Worker
130*7c568831SAndroid Build Coastguard Worker {
131*7c568831SAndroid Build Coastguard Worker if (!cd || cd == (Iconv_t) -1) {
132*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
133*7c568831SAndroid Build Coastguard Worker return (size_t) -1;
134*7c568831SAndroid Build Coastguard Worker }
135*7c568831SAndroid Build Coastguard Worker
136*7c568831SAndroid Build Coastguard Worker return iconv(*(iconv_t *) cd, inbuf, inbytesleft, outbuf, outbytesleft);
137*7c568831SAndroid Build Coastguard Worker }
138*7c568831SAndroid Build Coastguard Worker
139*7c568831SAndroid Build Coastguard Worker
140*7c568831SAndroid Build Coastguard Worker int
IconvClose(Iconv_t cd)141*7c568831SAndroid Build Coastguard Worker IconvClose(Iconv_t cd)
142*7c568831SAndroid Build Coastguard Worker
143*7c568831SAndroid Build Coastguard Worker {
144*7c568831SAndroid Build Coastguard Worker if (!cd || cd == (Iconv_t) -1) {
145*7c568831SAndroid Build Coastguard Worker errno = EINVAL;
146*7c568831SAndroid Build Coastguard Worker return -1;
147*7c568831SAndroid Build Coastguard Worker }
148*7c568831SAndroid Build Coastguard Worker
149*7c568831SAndroid Build Coastguard Worker if (iconv_close(*(iconv_t *) cd))
150*7c568831SAndroid Build Coastguard Worker return -1;
151*7c568831SAndroid Build Coastguard Worker
152*7c568831SAndroid Build Coastguard Worker free((char *) cd);
153*7c568831SAndroid Build Coastguard Worker return 0;
154*7c568831SAndroid Build Coastguard Worker }
155