ユニコードをRPGからIFSに書き込む
Question
RPG での IFS の連携に関する記事をたくさん読ませていただきました。ところが、テキスト・ファイルについて見られるどの例も、RPG プログラムで EBCDIC データを使用して、それを ASCII 形式で IFS に書き込んでいるものばかりです。RPG プログラムでユニコードを使用する場合はどうなるのでしょうか。ユニコードをどのように IFSに書き込めばいいのでしょうか。
Answer
RPG は本来、UCS-2 データ・タイプと %ucs2 組み込み関数 (BIF) を備えたユニコード文字をサポートしています。このサポートを利用して、ユニコード・データを変数に保存し、IFS API でそれらをディスクに書き込むことができます。ストリーム・ファイルに適切な CCSID を付けるよう注意する必要があります。
UCS-2 は旧規格ですが、D 仕様で CCSID(1200) を指定する場合、データは UTF-16 (これは CCSID 1200 が表現する内容です) と互換性があります。
図2 に例を示します。
例についていくつか注意点があります。
unlink() API は既存のファイルを削除します。この例では、/tmp/test.txt が既に存在する場合、それは削除されます。
O_CREAT フラグが open() API で指定されているため、そのファイルが作成されます。ファイルが作成されると、CCSID が割り当てられます。第 4 パラメーターに O_CCSID フラグと 1200 を指定したため、ファイルには CCSID 1200 とマークが付けられます。
open() コールで O_TEXTDATA を指定しなかったことに気が付くでしょう。これは、API がデータを変換しないことを意味します。私のデータは既にユニコードであるため、変換を有効にしても意味がありません。
write() API では、ストリング長の 2 倍の長さを指定しています。UTF-16 は各文字に 2 バイト使用しているためです。
前出のコードにより、IFS でユニコード・ファイルを簡単に作成できるはずです。UTF-16 より UTF-8 の方がご使用のアプリケーションに適している場合は、open() API に多少の変換をさせるのは理にかなっているかもしれません。その場合、UTF-16 から始めて (EBCDIC より幅広い文字に対応しているためです)、API にデータを CCSID 1208 である UTF-8 に変換するよう依頼します。
図3 でおわかりのように、ファイルには CCSID 1208 とマークが付けられ、テキスト・モードで開いています。そのファイルに書き込まれたデータは CCSID 1200 (UTF-16) から CCSID 1208 (UTF-8) に変換されます。するとどうでしょう。ファイルは UTF-8 になりますが、すべてのユニコード文字をサポートしています。