RPG

180. RPG で Unicode ファイルを IFS に出力するには ? (2)

前項の紹介で示したように RPG の BIFF 関数である %UCS2 で漢字を Unicode に変換することは
できない。さらに %UCS2 では UTF-8 へ変換することはできない。
つまり %UCS2 では、ほとんど Unicode への変換の機能を期待することはできない。
そこで、ここでは EnterpriseServer で提供されているサービス・プログラム UNI_CODE を使って
UTF-8 へ変換する方法を紹介しよう。

【 サンプル: TESTUNI2 】
-------------------------------------------------------------------------------------------
0001.00 H DFTNAME(TESTUNI) DATEDIT(*YMD/) BNDDIR('QC2LE')                              
0002.00 F******** IFS への UNICODE 出力 ***************************************        
0003.00 F*                                                                             
0004.00 F*   CRTRPGMOD QTEMP/TESTUNI2 SRCFILE(PGMRLIB/QRPGLESRC) AUT(*ALL)             
0005.00 F*   CRTPGM    OBJLIB/TESTUNI2 MODULE(QTEMP/TESTUNI2)                          
0006.00 F*               SRVPGM(QSYS/QP0LLIB1 ASNET.COM/UNI_CODE) AUT(*ALL)            
0007.00 F*                                                                             
0008.00 F**********************************************************************        
0009.00 D FD              S             10I 0                                          
0010.00 D DATA            S            128A                                            
0011.00 D UTF             S            128A                                            
0012.00                                                                                
0013.00 D OPEN_           PR            10I 0 EXTPROC('open')                          
0014.00 D  PATH                           *   VALUE                                    
0015.00 D  FLAG                         10I 0 VALUE                                    
0016.00 D  MODE                         10I 0 VALUE OPTIONS(*NOPASS)                   
0017.00 D  CODEPAGE                     10I 0 VALUE OPTIONS(*NOPASS)                   
0018.00 D  TOPAGE                       10I 0 VALUE OPTIONS(*NOPASS)                   
0019.00                                                                                
0020.00 D WRITE_          PR            10I 0 EXTPROC('write')                         
0021.00 D  DESC                         10I 0 VALUE                                    
0022.00 D  DATA                           *   VALUE                                    
0023.00 D  DTALEN                       10I 0 VALUE                                    
0024.00                                                                         
0025.00 D CLOSE_          PR                  EXTPROC('close')                  
0026.00 D  DESC                         10I 0 VALUE                             
0027.00                                                                         
0028.00 D PERROR_         PR                  EXTPROC('perror')                 
0029.00 D  STR                            *   VALUE                             
0030.00                                                                         
0031.00 D TO_UTF8         PR            10I 0 EXTPROC('toUTF8')                 
0032.00 D  SRCSTR                         *   VALUE                             
0033.00 D  TGTSTR                         *   VALUE                             
0034.00 D  CONTRY                       10I 0 VALUE                             
0035.00                                                                         
0036.00 D O_CREAT         S             10I 0 INZ(8)                            
0037.00 D O_TRUNC         S             10I 0 INZ(64)                           
0038.00 D O_CCSID         S             10I 0 INZ(32)                           
0039.00 D O_WRONLY        S             10I 0 INZ(2)                            
0040.00 D S_IWUSR         S             10I 0 INZ(128)                          
0041.00 D S_IRUSR         S             10I 0 INZ(256)                          
0042.00 D PATH            S             14A   INZ('/A001/TEST.TXT')             
0043.00 D MSG             S             80A   INZ(' オープン・エラーです ')     
0044.00                                                                         
0045.00 D USA             S             10I 0 INZ(0)                            
0046.00 D JPN             S             10I 0 INZ(1)                            
0047.00 D CHN             S             10I 0 INZ(2)                            
0048.00 D HKG             S             10I 0 INZ(3)                
0049.00 D KOR             S             10I 0 INZ(4)                
0050.00 D TAI             S             10I 0 INZ(5)                
0051.00 D GER             S             10I 0 INZ(6)                
0052.00 D Shift_JIS       S             10I 0 INZ(7)                
0053.00                                                            
0054.00 D LEN             S             10I 0                      
0055.00  /FREE                                                     
0056.00      FD = OPEN_(%ADDR(PATH):                               
0057.00                O_CREAT + O_TRUNC + O_CCSID + O_WRONLY :    
0058.00                S_IWUSR + S_IRUSR :                         
0059.00                1208);                                      
0060.00     IF (FD < 0);                                           
0061.00        PERROR_(%ADDR(MSG));                                
0062.00        RETURN;                                             
0063.00     ENDIF;                                                 
0064.00     DATA = ' こんにちは UTF-8' + X'00';                    
0065.00     LEN = TO_UTF8(%ADDR(DATA): %ADDR(UTF): JPN);           
0066.00     IF (LEN > 0);                                          
0067.00        WRITE_(FD : %ADDR(UTF) : LEN);                      
0068.00     ENDIF;                                                 
0069.00     CLOSE_(FD);                                            
0070.00     *INLR = *ON;                                           
0071.00  /END-FREE 
-------------------------------------------------------------------------------------------
【 コンパイル 】
CRTRPGMOD MODULE(QTEMP/TESTUNI2) SRCFILE(MYSRCLIB/QRPGLESRC) AUT(*ALL)
CRTPGM PGM(OBJLIB/TESTUNI2) MODULE(QTEMP/TESTUNI2) BNDSRVPGM(ASNET.COM/UNI_CODE) ACTGRP(*NEW) AUT(*ALL)
【 解説 】

UNI_CODE *SRVPGMtoUTF8 関数のプロトタイプを定義しているのが

0031.00 D TO_UTF8         PR            10I 0 EXTPROC('toUTF8')                 
0032.00 D  SRCSTR                         *   VALUE                             
0033.00 D  TGTSTR                         *   VALUE                             
0034.00 D  CONTRY                       10I 0 VALUE 

であり、実際に UTF-8 に変換しているのが

0065.00     TO_UTF8(%ADDR(DATA): %ADDR(UTF): JPN); 

である。パラメータ JPN は日本語からの変換を指示しており

0045.00 D USA             S             10I 0 INZ(0)                            
0046.00 D JPN             S             10I 0 INZ(1)                            
0047.00 D CHN             S             10I 0 INZ(2)                            
0048.00 D HKG             S             10I 0 INZ(3)                
0049.00 D KOR             S             10I 0 INZ(4)                
0050.00 D TAI             S             10I 0 INZ(5)                
0051.00 D GER             S             10I 0 INZ(6)                
0052.00 D Shift_JIS       S             10I 0 INZ(7)

で示されているように英語、日本語、中国語(簡体字), 中国語(繁体字), 韓国語、タイ語、ドイツ語、そして
Shift_JIS もサポートしている。
Shift_JIS とは ASCII Shift_JISUTF-8 との変換もサポートしている。

【 参考 】

UNI_CODE *SRVPGM を使わずに独力の力技でやってみようという豪傑ツワモノの人がいれば
API : iconv を使用することをお奨めする。
ただし iconv のパラメータは繊細であり、かなり面倒で正常に思うがままに動作するようになるまでは
時間を必要とすることを覚悟する必要がある。