Writing varying(2) and varying(4) Unicode data to the IFS codepage 1200 stream file in RPGLE |
RPGLE Program for IFS write unicode data varying(2) and varying(4)
In this article we would be creating the unicode enabled stream file and writing unicode data onto the stream file. Earlier we did writter character data and used write() api to write the character data. We will use the same api to write the unicode data as well.
RPGLE Program for Writing Unicode data to the IFS stream file in RPGLE
HDFTACTGRP(*NO) 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 Doflag s 10I 0 Dmode s 10U 0 Dcodepage s 10U 0 Dfiledescriptor s 10i 0 Difsdata s 11c inz ccsid(1200) varying Difsdata2 s 65536c inz ccsid(1200) varying Dreturn_write s 10i 0 inz Dreturn_close s 10i 0 inz C EVAL ifspath = '/home/easyclass/UCSfile2' 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 1200) C IF filedescriptor < 0 C RETURN C ENDIF C EVAL ifsdata = %UCS2('HELLO WORLD':1200) C EVAL return_write = write(filedescriptor: C %addr(ifsdata) + 2:%size(ifsdata)) C IF return_write < %size(ifsdata) C RETURN C ENDIF C EVAL ifsdata2 = %UCS2('HELLO WORLD AGAIN':1200) C EVAL return_write = write(filedescriptor: C %addr(ifsdata2) + 4:%size(ifsdata2)) C IF return_write < %size(ifsdata2) C RETURN C ENDIF C EVAL return_close = close(filedescriptor) C IF return_close = -1 C RETURN C ENDIF C EVAL *INLR = *ON C RETURN
HDFTACTGRP(*NO) 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 Doflag s 10I 0 Dmode s 10U 0 Dcodepage s 10U 0 Dfiledescriptor s 10i 0 Difsdata s 11c inz ccsid(1200) varying Difsdata2 s 65536c inz ccsid(1200) varying Dreturn_write s 10i 0 inz Dreturn_close s 10i 0 inz /free ifspath = '/home/easyclass/UCSfile2'; oflag = O_writeonly + O_createfileifnotexist + O_converttextbycodepage ; mode = M_readowner + M_writeowner + M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode: 1200); if filedescriptor < 0; return; endif; ifsdata = %UCS2('HELLO WORLD':1200); return_write = write(filedescriptor:%addr(ifsdata) + 2:%size(ifsdata)); if return_write < %size(ifsdata); return; endif; ifsdata2 = %UCS2('HELLO WORLD AGAIN':1200); return_write = write(filedescriptor:%addr(ifsdata2) + 4:%size(ifsdata2)); if return_write < %size(ifsdata2); return; endif; return_close = close(filedescriptor); if return_close = -1; return; endif; *inlr = *on; return; /end-free
**FREE CTL-OPT DFTACTGRP(*NO); 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 UCS2(11) CCSID(1200) inz varying; DCL-S ifsdata2 UCS2(65536) CCSID(1200) inz varying; DCL-S return_write int(10) inz; DCL-S return_close int(10) inz; ifspath = '/home/easyclass/UCSfile2'; oflag = O_writeonly + O_createfileifnotexist + O_converttextbycodepage ; mode = M_readowner + M_writeowner + M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode: 1200); if filedescriptor < 0; return; endif; ifsdata = %UCS2('HELLO WORLD':1200); return_write = write(filedescriptor:%addr(ifsdata) + 2:%size(ifsdata)); if return_write < %size(ifsdata); return; endif; ifsdata2 = %UCS2('HELLO WORLD AGAIN':1200); return_write = write(filedescriptor:%addr(ifsdata2) + 4:%size(ifsdata2)); if return_write < %size(ifsdata2); return; endif; return_close = close(filedescriptor); if return_close = -1; return; endif; *inlr = *on; return;
Explanation of the above code
ifspath = '/home/easyclass/UCSfile2'; oflag = O_writeonly + O_createfileifnotexist + O_converttextbycodepage ; mode = M_readowner + M_writeowner + M_executeowner; filedescriptor = open(%trim(ifspath): oflag: mode: 1200); if filedescriptor < 0; return; endif;
First step is to create the ifs stream file that is unicode enabled using UCS-2 CCSID 1200. Here, we call open() api to create unicode enabled file named UCSfile2 on the user home directory. Pass the parameter ifspath, oflag and mode at the time of file creation. In oflag we will pass write only, create file if not exist and convert text by codepage flags and in mode we have passed authority flags for ownwer (read, write and execute) and at last codepage 1200 as the 4th optional parameter. So, the file created with ccsid 1200 will be unicode enabled and when the data written to it will be converted to ccsid 1200. Here, we checked if the return value by the open() api i.e. filedescriptor is less than zero then return from the program.
ifsdata = %UCS2('HELLO WORLD':1200); return_write = write(filedescriptor:%addr(ifsdata) + 2:%size(ifsdata)); if return_write < %size(ifsdata); return; endif;
Here, we convert the data to the unicode by using %UCS2 function with ccsid 1200. We call the write() api to write the varying(2) unicode data by passing the filedescriptor being returned by the open() api and address of varying(2) UCS2 defined variable named ifsdata + 2 and size of the ifsdata variable (size would be double from the character variable of same length). If the reurn value is less than the size of the ifsdata then return from the program since some issue occurred in writing all the bytes.
Please note that when we pass ifsdata variable then we pass %addr(ifsdata) + 2 in second parameter of write() api just because ifsdata is UCs2 field of length 11 (less than 65535) which is varying(2) i.e. the first two bytes contains the actual length of the data hold by the variable ifsdata and we start writing the content from the starting third byte of the ifsdata.
ifsdata2 = %UCS2('HELLO WORLD AGAIN':1200); return_write = write(filedescriptor:%addr(ifsdata2) + 4:%size(ifsdata2)); if return_write < %size(ifsdata2); return; endif;
Here, we convert the data to the unicode by using %UCS2 function with ccsid 1200. We call the write() api to write the varying(4) unicode data by passing the filedescriptor being returned by the open() api and address of varying(4) UCS2 defined variable named ifsdata2 + 4 and size of the ifsdata2 variable (size would be double from the character variable of same length). If the reurn value is less than the size of the ifsdata2 then return from the program since some issue occurred in writing all the bytes.
Please note that when we pass ifsdata2 variable then we pass %addr(ifsdata2) + 2 in second parameter of write() api just because ifsdata2 is UCs2 field of length 65536 (greater than 65535) which is varying(4) i.e. the first four bytes contains the actual length of the data hold by the variable ifsdata2 and we start writing the content from the starting fifth byte of the ifsdata.
return_close = close(filedescriptor); if return_close = -1; return; endif; *inlr = *on; return;
Finally, close the file using close() api and passing filedescriptor returned from the open() api. If the return value from close() api is less than zero then error in closing ifs stream file and and return abnormally from the program otherwise return normally from the program.