Using Code pages with Text files in IFS |
We already created the text file on the ifs but that is in EBCDIC format. We can read that text file on IBM i as IBM i uses EBCDIC format but if we download the same file on windows pc then that is of no use to us on the PC as the windows supports ASCII format.
We have an option to call iconv() api to convert the text to ASCII(codepage 819) before we actually write it to ifs text file but in that case our RPGLE programs find issue while reading the text data in ASCOO format since IBM i supports the EBCDIC format. This can be resolved using the codepage optional parameter in open() api that allows us to assign the codepage to the ifs stream file during its creation.
The O_converttextbycodepage flag on the open() api is used to inform the api that we are working with text data and we want the system to perform the same translation for us. When we read or write any data to the text file on the ifs, it will be automatically be translated to and from the codepage assigned to that text file on the ifs at the time of creation.
Here, code page 819 which represents ASCII.
RPGLE Program to to create ASCII text file on IFS and write data to text file
HDFTACTGRP(*NO) D unlink PR 10I 0 ExtProc('unlink') D ifspath * Value options(*string) D errorifs PR * ExtProc('__errno') D strerror PR * ExtProc('strerror') D error_num 10I 0 value D close PR 10i 0 extproc('close') * D fileds 10i 0 value *file descriptor D write PR 10i 0 extproc('write') * 32 bit, no. of byt D fileds 10i 0 value *file descriptor D buffer * value * pointer to byte D noofbytes 10U 0 value * 32 bits D open PR 10I 0 extproc('open') D ifspath * value options(*string) *ifs path D oflag 10I 0 value *string of 32 bits D mode 10U 0 value options(*nopass) * 9 bits D codepage 10U 0 value options(*nopass) * * <-----oflag----> D O_readonly C 1 D O_writeonly C 2 D O_readwrite C 4 D O_createfileifnotexist... D C 8 D O_exclusivecreate... D C 16 D O_truncateto0bytes... D C 64 D O_appendtofile C 256 D O_converttextbycodepage... D C 8388608 D O_openintextmode... D C 16777216 * * <-----mode----> * owner,group,other (RWX) * owner authority D M_readowner C 256 D M_writeowner C 128 D M_executeowner C 64 * group authority D M_readgroup C 32 D M_writegroup C 16 D M_executegroup C 8 * other people D M_readother C 4 D M_writeother C 2 D M_executeother C 1 * Difspath s 512a Dreturn_unlink s 10i 0 inz Doflag s 10I 0 Dmode s 10U 0 Dcodepage s 10U 0 Dfiledescriptor s 10i 0 Difsdata s 400a inz Dreturn_write s 10i 0 inz Dreturn_close s 10i 0 inz Derror_ptr S * Derror_num S 10I 0 based(error_ptr) Derrormsg_ptr S * Derror_msg S 500a based(errormsg_ptr) DCRLF C CONST(x'0D25') C EVAL ifspath = '/home/easyclass/txtfile2.txt' C EVAL return_unlink = unlink(%trim(ifspath)) C IF return_unlink < 0 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C ENDIF C EVAL oflag = O_writeonly + C O_createfileifnotexist + C O_converttextbycodepage C EVAL mode = M_readowner + C M_writeowner + C M_executeowner C EVAL filedescriptor = open(%trim(ifspath): C oflag: C mode: C 819) C IF filedescriptor < 0 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAL return_close = close(filedescriptor) C IF return_close = -1 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAL oflag = O_writeonly + C O_openintextmode C EVAL filedescriptor = open(%trim(ifspath): C oflag) C IF filedescriptor < 0 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAL ifsdata = 'IFS TEXT FILE1' + CRLF + C 'IFS TEXT FILE2' + CRLF + C CRLF + 'END' + CRLF C EVAL return_write = write(filedescriptor: C %addr(ifsdata): C %size(ifsdata)) C IF return_write < 0 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C IF return_close = -1 C EVAL error_ptr = errorIFS() C EVAL errormsg_ptr = strerror(error_num) C RETURN C ENDIF C EVAL *INLR = *ON C RETURN
HDFTACTGRP(*NO) D unlink PR 10I 0 ExtProc('unlink') D ifspath * Value options(*string) D errorifs PR * ExtProc('__errno') D strerror PR * ExtProc('strerror') D error_num 10I 0 value D close PR 10i 0 extproc('close') * D fileds 10i 0 value *file descriptor D write PR 10i 0 extproc('write') * 32 bit, no. of byt D fileds 10i 0 value *file descriptor D buffer * value * pointer to byte D noofbytes 10U 0 value * 32 bits D open PR 10I 0 extproc('open') D ifspath * value options(*string) *ifs path D oflag 10I 0 value *string of 32 bits D mode 10U 0 value options(*nopass) * 9 bits D codepage 10U 0 value options(*nopass) * * <-----oflag----> D O_readonly C 1 D O_writeonly C 2 D O_readwrite C 4 D O_createfileifnotexist... D C 8 D O_exclusivecreate... D C 16 D O_truncateto0bytes... D C 64 D O_appendtofile C 256 D O_converttextbycodepage... D C 8388608 D O_openintextmode... D C 16777216 * * <-----mode----> * owner,group,other (RWX) * owner authority D M_readowner C 256 D M_writeowner C 128 D M_executeowner C 64 * group authority D M_readgroup C 32 D M_writegroup C 16 D M_executegroup C 8 * other people D M_readother C 4 D M_writeother C 2 D M_executeother C 1 * Difspath s 512a Dreturn_unlink s 10i 0 inz Doflag s 10I 0 Dmode s 10U 0 Dcodepage s 10U 0 Dfiledescriptor s 10i 0 Difsdata s 400a inz Dreturn_write s 10i 0 inz Dreturn_close s 10i 0 inz Derror_ptr S * Derror_num S 10I 0 based(error_ptr) Derrormsg_ptr S * Derror_msg S 500a based(errormsg_ptr) DCRLF C CONST(x'0D25') /free ifspath = '/home/easyclass/txtfile2.txt'; return_unlink = unlink(%trim(ifspath)); if return_unlink < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); endif; oflag = O_writeonly + O_createfileifnotexist + O_converttextbycodepage; mode = M_readowner + M_writeowner + M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode: 819); if filedescriptor < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; return_close = close(filedescriptor); if return_close = -1; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; oflag = O_writeonly + O_openintextmode; filedescriptor = open(%trim(ifspath): oflag); if filedescriptor < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; ifsdata = 'IFS TEXT FILE1' + CRLF + 'IFS TEXT FILE2' + CRLF + CRLF + 'END' + CRLF; return_write = write(filedescriptor:%addr(ifsdata):%size(ifsdata)); if return_write < %size(ifsdata); error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; return_close = close(filedescriptor); if return_close = -1; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; *inlr = *on; return; /end-free
**FREE CTL-OPT DFTACTGRP(*NO); DCL-PR unlink int(10) EXTPROC('unlink'); ifspath pointer VALUE options(*string); END-PR; DCL-PR errorifs pointer EXTPROC('__errno'); END-PR; DCL-PR strerror pointer EXTPROC('strerror'); error_num int(10) VALUE; END-PR; DCL-PR write int(10) EXTPROC('write'); fileds int(10) VALUE; buffer pointer VALUE; noofbytes uns(10) VALUE; END-PR; DCL-PR open int(10) EXTPROC('open'); ifspath pointer VALUE options(*string); oflag int(10) VALUE; mode uns(10) VALUE options(*nopass); codepage uns(10) VALUE options(*nopass); END-PR; DCL-PR close int(10) EXTPROC('close'); fileds int(10) VALUE; END-PR; // * <-----oflag----> DCL-C O_readonly 1; DCL-C O_writeonly 2; DCL-C O_readwrite 4; DCL-C O_createfileifnotexist 8; DCL-C O_exclusivecreate 16; DCL-C O_truncateto0bytes 64; DCL-C O_appendtofile 256; DCL-C O_converttextbycodepage 8388608; DCL-C O_openintextmode 16777216; // * <-----mode----> // * owner,group,other (RWX) // * owner authority DCL-C M_readowner 256; DCL-C M_writeowner 128; DCL-C M_executeowner 64; // * group authority DCL-C M_readgroup 32; DCL-C M_writegroup 16; DCL-C M_executegroup 8; // * other people DCL-C M_readother 4; DCL-C M_writeother 2; DCL-C M_executeother 1; DCL-S ifspath CHAR(512); DCL-S oflag int(10); DCL-S mode uns(10); DCL-S codepage uns(10); DCL-S filedescriptor int(10); DCL-S ifsdata char(500) inz; DCL-S return_unlink int(10) inz; DCL-S return_write int(10) inz; DCL-S return_close int(10) inz; DCL-S error_ptr pointer; DCL-S error_num int(10) based(error_ptr); DCL-S errormsg_ptr pointer; DCL-S error_msg char(500) based(errormsg_ptr); DCL-C CRLF CONST(x'0D25'); ifspath = '/home/easyclass/txtfile2.txt'; return_unlink = unlink(%trim(ifspath)); if return_unlink < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); endif; oflag = O_writeonly + O_createfileifnotexist + O_converttextbycodepage; mode = M_readowner + M_writeowner + M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode: 819); if filedescriptor < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; return_close = close(filedescriptor); if return_close = -1; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; oflag = O_writeonly + O_openintextmode; filedescriptor = open(%trim(ifspath): oflag); if filedescriptor < 0; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; ifsdata = 'IFS TEXT FILE1' + CRLF + 'IFS TEXT FILE2' + CRLF + CRLF + 'END' + CRLF; return_write = write(filedescriptor:%addr(ifsdata):%size(ifsdata)); if return_write < %size(ifsdata); error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; return_close = close(filedescriptor); if return_close = -1; error_ptr = errorIFS(); errormsg_ptr = strerror(error_num); return; endif; *inlr = *on; return;
Exaplanation of above code
Everything is same as explained here for creating and writing text file on ifs except few things that are explained below