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