117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat/**
217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat***     iconv_open(), iconv(), iconv_close() wrappers for the OS/400.
317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat***
417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat***     See Copyright for the status of this software.
517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat***
617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat***     Author: Patrick Monnerat <pm@datasphere.ch>, DATASPHERE S.A.
717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat**/
817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#include <errno.h>
1017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#include <stdio.h>
1117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#include <stdlib.h>
1217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
1317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#include "/QIBM/include/iconv.h"        /* Force system definition. */
1417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
1517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#define USE_SYSTEM_ICONV
1617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#include "iconv.h"                      /* Use local definitions. */
1717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
1817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
1917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
2017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat/**
2117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat***     Bring-in the name-->CCSID mapping DFA tables.
2217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat**/
2317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
2417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat#include "ianatables.c"
2517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
2617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
2717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
2817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monneratstatic int
2917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick MonneratfindEncoding(const unsigned char * * namep)
3017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
3117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat{
3217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        t_staterange curstate;
3317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        t_ccsid ccsid;
3417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        t_ccsid final;
3517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        t_transrange l;
3617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        t_transrange h;
3717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        const unsigned char * name;
3817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
3917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        /**
4017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        ***     Get the CCSID correspong to the name at *`namep'.
4117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        ***     If success, update pointer at `namep' to 1st byte after matched
4217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        ***             name and return the CCSID.
4317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        ***     If failure, set errno and return -1.
4417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        **/
4517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
4617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (!namep || !(name = *namep)) {
4717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                errno = EINVAL;
4817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return -1;
4917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                }
5017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
5117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        curstate = 0;
5217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        final = 0;
5317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
5417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        for (;;) {
5517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                if (curstate < sizeof final_array / sizeof final_array[0])
5617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                        if (final_array[curstate]) {
5717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                final = final_array[curstate];
5817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                *namep = name;
5917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                }
6017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
6117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                l = trans_array[curstate] - 1;
6217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                h = trans_array[curstate + 1];
6317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
6417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                do {
6517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                        if (++l >= h) {
6617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                if (!final) {
6717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                        errno = EINVAL;
6817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                        return -1;
6917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                        }
7017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
7117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                return final - 1;
7217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                }
7317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                } while (label_array[l] != *name);
7417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
7517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                curstate = goto_array[l];
7617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                name++;
7717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                }
7817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
7917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        /* NOTREACHED. */
8017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat}
8117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
8217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
8317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monneratstatic void
8417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monneratmakeos400codename(char * buf, unsigned int ccsid)
8517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
8617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat{
8717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        ccsid &= 0xFFFF;
8817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        memset(buf, 0, 32);
8917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        sprintf(buf, "IBMCCSID%05u0000000", ccsid);
9017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat}
9117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
9217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
9317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick MonneratIconv_t
9417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick MonneratIconvOpen(const char * tocode, const char * fromcode)
9517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
9617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat{
9717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        int toccsid = findEncoding(&tocode);
9817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        int fromccsid = findEncoding(&fromcode);
9917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        char fromibmccsid[33];
10017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        char toibmccsid[33];
10117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        iconv_t * cd;
10217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
10317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (toccsid < 0 || fromccsid < 0)
10417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return (Iconv_t) -1;
10517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
10617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        makeos400codename(fromibmccsid, fromccsid);
10717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        makeos400codename(toibmccsid, toccsid);
10817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        memset(toibmccsid + 13, 0, sizeof toibmccsid - 13);
10917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
11017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        cd = (iconv_t *) malloc(sizeof *cd);
11117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
11217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (!cd)
11317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return (Iconv_t) -1;
11417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
11517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        *cd = iconv_open(toibmccsid, fromibmccsid);
11617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
11717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (cd->return_value) {
11817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                free((char *) cd);
11917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return (Iconv_t) -1;
12017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                }
12117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
12217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        return (Iconv_t) cd;
12317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat}
12417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
12517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
12617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monneratsize_t
12717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick MonneratIconv(Iconv_t cd, char * * inbuf, size_t * inbytesleft,
12817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                                        char * * outbuf, size_t * outbytesleft)
12917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
13017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat{
13117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (!cd || cd == (Iconv_t) -1) {
13217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                errno = EINVAL;
13317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return (size_t) -1;
13417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                }
13517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
13617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        return iconv(*(iconv_t *) cd, inbuf, inbytesleft, outbuf, outbytesleft);
13717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat}
13817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
13917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
14017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monneratint
14117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick MonneratIconvClose(Iconv_t cd)
14217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
14317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat{
14417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (!cd || cd == (Iconv_t) -1) {
14517951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                errno = EINVAL;
14617951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return -1;
14717951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                }
14817951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
14917951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        if (iconv_close(*(iconv_t *) cd))
15017951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat                return -1;
15117951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat
15217951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        free((char *) cd);
15317951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat        return 0;
15417951ea28989d6ca70697cef7bfeeceebf4d94c5Patrick Monnerat}
155