This installment of "APIs by Example" offers sample RPG code showing how to read a text line from an IFS file until a line terminator is encountered, and also how to write a line to an IFS file.
The sample code consists of three RPG IV programs that create and read three text files in QOpenSys to show how the APIs work. Here are the programs:
CBX002A
Creates stream files /QOpenSys/access001.log and
/QOpenSys/access002.log.
CBX002B
Creates file /QOpenSys/access00x.log, reads the access001.log and
access002.log files, and appends them to access00x.log.
CBX002C
Reads access00x.log, then deletes the example stream files.
The sample RPG IV programs use seven C library functions, listed below:
Open stream file (fopen)
Opens or creates the specified stream file. The access level required
is defined by the mode parameter and is followed by an optional
keyword parameter specifying various file attributes.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.48
Read stream (fgets)
Reads characters from current stream position for the number of bytes
specified by the second parameter or until new-line character or end-
of-stream is encountered. The new-line character (x'25') is included
in the retrieved string.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.42
Write stream (fputs)
Appends the string parameter to the current stream position. The
number of bytes written is returned.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.51
Close stream (fclose)
Closes the stream pointed to by the FILE structure.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.35
Delete stream file (remove)
Deletes the specified stream file.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.136
Get error number (errno)
Retrieves the current value of the C runtime error number variable.
The errno function simply returns a pointer to a 4-byte integer.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at702/9.1.2
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.3.1
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.3.2
Map error number (strerror)
Converts the error number variable to an error message string.
http://publib.boulder.ibm.com/cgi-bin/bookmgr/bookmgr.cmd/BOOKS/qb3at500/1.2.184
Below is the sample RPG IV code.
** Program: CBX002A ** Description: Create files used by IFS file API example. ** Compile: CRTBNDRPG ... DBGVIEW(*LIST) ** **-- Control spec: -----------------------------------------------** H Option( *SrcStmt ) DftActGrp( *No ) BndDir( 'QC2LE' ) **-- Global variables: -------------------------------------------** D FILE_o s * D String s 512a D rc s 10i 0 D Idx s 5u 0 **-- Global constants: -------------------------------------------** D FilNam_1 c '/QOpenSys/access001.log' D FilNam_2 c '/QOpenSys/access002.log' D LF c x'25' **-- IFS stream file functions: ----------------------------------** Dopen Pr * ExtProc( '_C_IFS_fopen' ) D * Value Options( *String ) D * Value Options( *String ) ** Dfgets Pr * ExtProc( '_C_IFS_fgets' ) D * Value D 10i 0 Value D * Value ** Dfputs Pr 10i 0 ExtProc( '_C_IFS_fputs' ) D * Value Options( *String ) D * Value ** Dclose Pr 10i 0 ExtProc( '_C_IFS_fclose' ) D * Value ** **-- Mainline: ------------------------------------------------------ ---** ** **-- create file, set codepage (pc): C Eval FILE_o = open( %TrimR( FilNam_1 ) C : 'w, codepage=850' C ) ** C Eval rc = close( FILE_o ) ** C Eval FILE_o = open( %TrimR( FilNam_2 ) C : 'w, codepage=850' C ) ** C Eval rc = close( FILE_o ) ** **-- open files, implicit conversion to job codepage: C Eval FILE_o = open( %TrimR( FilNam_1 ) C : 'w' C ) ** C If FILE_o <> *Null ** C For Idx = 1 to 10 C Eval rc = fputs( 'Stream 1 line: ' + C %Char( Idx ) + C LF C : FILE_o C ) C EndFor ** C Eval rc = close( FILE_o ) C EndIf ** **-- open files, implicit conversion to job codepage: C Eval FILE_o = open( %TrimR( FilNam_2 ) C : 'w' C ) ** C If FILE_o <> *Null ** C For Idx = 1 to 10 C Eval rc = fputs( 'Stream 2 line: ' + C %Char( Idx ) + C LF C : FILE_o C ) C EndFor ** C Eval rc = close( FILE_o ) C EndIf ** C Eval *InLr = *On C Return ** Program: CBX002B ** Description: Read two files, and append them to a third new file. ** Compile: CRTBNDRPG ... DBGVIEW(*LIST) ** ** **-- Control spec: ------------------------------------------------** H Option( *SrcStmt ) DftActGrp( *No ) BndDir( 'QC2LE' ) **-- Global variables: --------------------------------------------** D FILE_i s * D FILE_o s * D ErrTxt s 128a D String s 512a D rc s 10i 0 **-- Global constants: --------------------------------------------** D FilNam_1 c '/QOpenSys/access001.log' D FilNam_2 c '/QOpenSys/access002.log' D FilNam_o c '/QOpenSys/access00x.log' **-- Error identification: ----------------------------------------** D errno Pr 10i 0 ** D strerror Pr 128a Varying **-- IFS stream file functions: -----------------------------------** Dopen Pr * ExtProc( '_C_IFS_fopen' ) D * Value Options( *String ) D * Value Options( *String ) ** Dfgets Pr * ExtProc( '_C_IFS_fgets' ) D * Value D 10i 0 Value D * Value ** Dfputs Pr 10i 0 ExtProc( '_C_IFS_fputs' ) D * Value Options( *String ) D * Value ** Dclose Pr 10i 0 ExtProc( '_C_IFS_fclose' ) D * Value ** **-- Mainline: ----------------------------------------------------** ** **-- create file, set codepage (pc): C Eval FILE_o = open( %TrimR( FilNam_o ) C : 'w, codepage=850' C ) ** C Eval rc = close( FILE_o ) ** **-- open files, implicit conversion to job codepage: C Eval FILE_o = open( %TrimR( FilNam_o ) C : 'w' C ) ** C Eval FILE_i = open( %TrimR( FilNam_1 ) C : 'r' C ) ** C If FILE_i = *Null C Eval ErrTxt = %Char( Errno ) + ': ' + C Strerror C Else ** C Dow fgets( %Addr( String ) C : %Size( String ) C : FILE_i C ) <> *Null **-- copy file 1 to new file... C Eval rc = fputs( %Str( %Addr( String )) C : FILE_o C ) C EndDo ** C Eval rc = close( FILE_i ) C EndIf ** C Eval FILE_i = open( %TrimR( FilNam_2 ) C : 'r' C ) ** C If FILE_i = *Null C Eval ErrTxt = %Char( Errno ) + ': ' + C Strerror C Else ** C Dow fgets( %Addr( String ) C : %Size( String ) C : FILE_i C ) <> *Null **-- copy file 2 to new file... C Eval rc = fputs( %Str( %Addr( String )) C : FILE_o C ) C EndDo ** C Eval rc = close( FILE_i ) C EndIf C Eval rc = close( FILE_o ) ** C Eval *InLr = *On C Return ** **-- Get runtime error number: ------------------------------------** P Errno B D Pi 10i 0 D sys_errno Pr * ExtProc( '__errno' ) ** D Error s 10i 0 Based( pError ) NoOpt ** C Eval pError = sys_errno C Return Error ** P Errno E **-- Get runtime error text: --------------------------------------** P Strerror B D Pi 128a Varying D sys_strerror Pr * ExtProc( 'strerror' ) D 10i 0 Value ** C Return %Str( sys_strerror( Errno )) ** P Strerror E ** Program: CBX002C ** Description: Read merged file and clean up IFS example files. ** Compile: CRTBNDRPG ... DBGVIEW(*LIST) ** **-- Control spec: ------------------------------------------------** H Option( *SrcStmt ) DftActGrp( *No ) BndDir( 'QC2LE' ) **-- Global variables: --------------------------------------------** D FILE_i s * D String s 512a D rc s 10i 0 D Idx s 5u 0 **-- Global constants: --------------------------------------------** D FilNam_o c '/QOpenSys/access00x.log' D FilNam_1 c '/QOpenSys/access001.log' D FilNam_2 c '/QOpenSys/access002.log' **-- IFS stream file functions: -----------------------------------** Dopen Pr * ExtProc( '_C_IFS_fopen' ) D * Value Options( *String ) D * Value Options( *String ) ** Dfgets Pr * ExtProc( '_C_IFS_fgets' ) D * Value D 10i 0 Value D * Value ** Dfputs Pr 10i 0 ExtProc( '_C_IFS_fputs' ) D * Value Options( *String ) D * Value ** Dclose Pr 10i 0 ExtProc( '_C_IFS_fclose' ) D * Value ** Dremove Pr 10i 0 ExtProc( '_C_IFS_remove' ) D * Value Options( *String ) ** **-- Mainline: ----------------------------------------------------** ** C Eval FILE_i = open( %TrimR( FilNam_o ) C : 'r' C ) ** C Dow fgets( %Addr( String ) C : %Size( String ) C : FILE_i C ) <> *Null C EndDo ** C Eval rc = close( FILE_i ) ** C Eval rc = remove( %TrimR( FilNam_o )) C Eval rc = remove( %TrimR( FilNam_1 )) C Eval rc = remove( %TrimR( FilNam_2 )) ** C Eval *InLr = *On C Return
The above tip was written by Carsten Flensburg. For questions regarding this tip, contact Carsten at mailto:flensburg@novasol.dk.