Skip to main content  
        iSeries home   |   Easy400     |   CGIDEV2  

Converting IFS strings
by Giovanni B. Perotti (Italy)

Reading stream files

Reading an IFS stream file through an ILE-RPG program is usually no problem, as the stream file data can be automatically translated from the stream file code page to the job CCSID.

Let us take, as an example, the stream file containing this page, /cvt101/html/intro.htm, code page 819. The ILE-RPG code to read it is pretty simple:

D Stmf            s            256    inz('/cvt101/html/intro.htm')
D Handle          s             10i 0                             
D Buffer          s          10000                                
D DataLen         s             10i 0                             
D rc              s             10i 0                             
D O_RDONLY        s             10i 0 inz(1)                      
D O_TEXTDATA      s             10i 0 inz(16777216)               
D open            pr            10i 0 extproc('open')             
D  filename                       *   value options(*string)      
D  openflags                    10i 0 value                       
D  mode                         10u 0 value options(*nopass)      
D  codepage                     10u 0 value options(*nopass)      
D read            pr            10i 0 extproc('read')             
D  filehandle                   10i 0 value                       
D  datareceived                   *   value                       
D  nbytes                       10u 0 value                       
D close           pr            10i 0 extproc('close')            
D  filehandle                   10i 0 value                       
 * Open the stream file                                           
C                   eval      Handle = open(%trim(Stmf) 
C                             :O_RDONLY + O_TEXTDATA)   
 * Loop to read the stream file into "Buffer"           
C                   eval      DataLen=1                 
C                   dow       DataLen>0                 
C                   eval      DataLen=read(Handle:      
C                             %addr(Buffer):            
C                             %size(Buffer))            
 *                    ... process stream file data ...  
C                   enddo                               
 * Close the stream file                                
C                   eval      rc= close(Handle)         
 * Back to caller                                       
C                   return

The data read into the buffer are automatically converted to the job CCSID (or to the job default CCSID, if the job CCSID is 65535). This is why the program can understand and process (if needed) that data.
This is done by specifying the flag O_TEXTDATA on the open() of the stream file. See this page of the IBM iSeries Information Center.

Unicode stream files

Problem is that, if the stream file is in Unicode (code page 1208), any attempt to open() it by specifying O_TEXTDATA would fail. The question would then be: how can I process Unicode stream files?

The Iconv API

According to Wikipedia, "the iconv API is the standard programming interface for converting character strings from one character encoding to another in Unix-like operating systems."
The iconv API was made available on iSeries with release V5R2.
The iconv API is perfect for converting Unicode code page (1208) to any other code page or CCSID, including that of the running job. Obviously it can work the other way around.
The only problem is that it is not an easy API to deal with.

The CvtStg (Convert String) subprocedure

Library CVT101 contains a small service program CVT101/CVT101. This service program features a Convert String subprocedure, that would help in converting a string from one code page (CCSID) to another code page (CCSID) through the iconv API.
The following example shows how to use the CvtStg subprocedure:

 * Assume that 
 * 1-The string to be converted is in a buffer addressed by the following pointer
D SrcPointer      s               *
 *  -its length is defined by the following variable
D SrcLen          s             10u 0
 *  -that its code page (CCSID) is defined by the variable
D SrcCodePage     s             10u 0
 * 2-The buffer to receive the converted string is addressed by the following pointer
D TgtPointer      s               *
 *  -its maximum length is defined by the following variable
D TgtMaxLen       s             10u 0
 *  -the variable to receive its computed length is
D TgtLen          s             10u 0
 *  -and the target code page is defined in
D TgtCodePage     s             10u 0
 * Define two more variables to save/restore the two string pointers
D SrcPointerSav   s               *
D TgtPointerSav   s               *

 *In order to call the subprocedure CvtStg you need the following prototype:
D CVTSTG          pr                 
D                               10u 0
D                                 *  
D                               10u 0
D                               10u 0
D                                 *  
D                               10u 0
D                               10u 0
 *This is how you perform the string conversion:
C                   eval      SrcPointerSav=SrcPointer                 
C                   eval      TgtPointerSav=TgtPointer                 
C                   callp     CvtStg(SrcCodePage:SrcPointer:SrcLen:
C                             TgtCodePage:TgtPointer:TgtMaxLen:TgtLen)
C                   eval      SrcPointer=SrcPointerSav                 
C                   eval      TgtPointer=TgtPointerSav

Command StmfCvt - Convert a stream file

This CVT101 command allows to convert a stream file from a code page to another code page:

                         Convert a stream file (STMFCVT)
 Type choices and press Enter.

 Source stream file . . . . . . . SRCSTMF                                       
 Target stream file . . . . . . . TGTSTMF                                       
 Target code page . . . . . . . . TGTCODEPAG    819    Number, *JOB, *UNICODE...

 Display target stream file . . . DSPTGT        *NO

Note 1- The code page of the source stream file does not have to be specified.
Note 2- The target stream file could be the same as the source stream file.
Note 3- The target code page can be specified as

  • a number lower than 65535 (e.g. 819 for U.S. ASCII, 1208 for Unicode)
  • *JOB to use the job CCSID as target code page
  • *UNICODE to mean code page 1208
  • *ASCII to mean code page 819

Command DirCvt - Convert all the stream files within a directory

This CVT101 command allows to convert to another code page all the stream files of a given directory:

                      Convert all STMF's in a dir (DIRCVT)
 Type choices and press Enter.                                           
 Source directory . . . . . . . . SRCDIR                                       
 Target directory . . . . . . . . TGTDIR                                       
 Target code page . . . . . . . . TGTCODEPAG    819    Number, *JOB, *UNICODE...

Note 4- The stream files in the directory could have different code pages.
Note 5- The target directory could be the same as the source directory.