バージョン 4.2.5
 —  Unicode およびコードページのサポート  —

Natural プログラミング言語での Unicode およびコードページのサポート

このドキュメントでは、次のトピックについて説明します。


Unicode ベースのデータ用の Natural データフォーマット U

Natural では、フォーマット U および U 定数を使用して Unicode 文字列を指定できます。

データフォーマット U は、エンディアンに依存します。 フォーマット B と U 間で移動する場合は、これを考慮する必要があります。

U と A の比較

A フォーマットと比較した U フォーマットの利点は、さまざまな言語の文字の任意の組み合わせを保持でき、デフォルトコードページ(システム変数 *CODEPAGE の値)に依存しない点です。 さらに、U フォーマットでは、異なるプラットフォーム間でのデータの共有が簡単です。変換(例えば、EBCDIC から ASCII へ)は必要ありません。

一方、U フォーマットデータは、A フォーマットデータよりも多くのメモリが消費されます。 ほとんどの文字列をシングルバイトエンコードで表すことができる言語の場合、U フォーマットでは、以前に必要だったスペースの 2 倍のスペースが文字列によって占められるようになります。 ただし、東アジア言語の場合は、通常、メモリ消費は増加しません。

Top of page

ステートメント

基本的に、A フォーマットを使用できるステートメントのほとんどで、U フォーマットを使用できます。 ただし、ステートメントのオペランドとして Natural オブジェクト名が与えられる場合(CALLNAT ステートメントなど)、Natural オブジェクト名は A フォーマットであるため、U を使用できません。 特定のステートメントの詳細については、『ステートメント』ドキュメントを参照してください。

基本的に、A および U フォーマットは、1 つのステートメント内で一緒に使用できます。次に例を示します。

EXAMINE S FOR P WITH DELIMITER D REPLACE R

S は U フォーマット、PD、および R は A フォーマットです。

上記の例では、変数 PD、および R がターゲットフォーマット U に一時的に変換されてから、EXAMINE ステートメントが実際に実行されます。 Unicode からコードページ、またはその逆の変換では、ICU 機能を呼び出す必要があります。 この変換には、コンピュータの時間およびメモリが追加で必要になります。 この短所は、大きな変数の場合にさらに顕著になります。 頻繁な変換を避けるために、1 つのステートメント内では 1 つのフォーマットのみを使用することをお勧めします。 上記の例のすべてのオペランドが U フォーマットまたは A フォーマットで指定されている場合は、変換は必要ありません。 ただし、U オペランドのみを指定することを選択した場合は、遅くなります。このオペランドタイプでは、その性質によってリソースが多く消費されるためです。この場合、1 文字が、A フォーマットで使用される 1 バイトではなく、2 バイトでコード化されます。

変換(特に、U フォーマットから A フォーマットへ)では、ターゲットコードページで文字を表現できないというリスクが常にあります。 例えば、Unicode 文字 "U+05D0"(ヘブライ文字のアレフ)をコードページ IBM01140(英語)に変換するとします。 この文字はコードページ IBM01140 に含まれていないため、このコードページの置換文字か、またはコードページの定義時に NATCONFG に指定されたプレースホルダ(メインフレームのみ)が使用されます。 パラメータ CPCVERR が "ON" に設定されている場合は、変換エラーを示すエラーメッセージがこの場合に表示されます。 いずれの場合にも、元の情報は失われます。

Unicode を使用する場合、特に次のステートメントに影響します。

MOVE NORMALIZED

Unicode での正規化:バイナリでの等価比較が可能な形式へデータを変換するために、同等のシーケンスの代替表現をテキストデータから削除するプロセス。 Unicode 標準では、さまざまな正規化形式が定義されています。 Unicode 文字列の正規分解の結果の正規化形式の後に、可能であればプライマリ合成による分解されたすべてのシーケンスに置き換わるものを付けた形式は、"合成済み正規化形式"(NFC)と呼ばれます。

Natural では、Unicode 文字を部分的に切り捨てることなく文字列処理を実行できるように、すべての Unicode データは NFC フォーマットであることが前提となっています。 Natural 変換処理では、結果として生じる Unicode 文字列は NFC であることが保証されます。 Natural の外部から Unicode データを受け取り、そのデータが NFC フォーマットであることが保証されない場合は、MOVE NORMALIZED ステートメントを適用できます。

例:

文字シーケンス NFC
ê (U+00EA) ê (U+00EA)
e (U+0065) + ^ (U+0302) ê (U+00EA)

注意:
NFC フォーマットの 2 つ以上の文字列を連結した場合、NFC フォーマットにならない場合があります。

MOVE ENCODED

MOVE ステートメントを使用して文字列を U から A へ、またはその逆に移動するときに、Unicode とデフォルトコードページ(システム変数 *CODEPAGE の値)の間の暗黙的な変換が実行されます。

さらに、異なるコードページ間の変換、または使用可能なコードページから Unicode への変換、およびその逆への変換に、MOVE ENCODED ステートメントを使用できます。 これは、Natural の外部からのデータがデフォルトコードページとは異なるコードページでコード化されている場合に役立ちます。 しかし、デフォルトコードページと Unicode 間の変換についても、GIVING 節での潜在的な変換エラーを取得する場合は、このステートメントを使用できます。この場合は、CPCVERR が "ON" に設定されている場合に、MOVE ステートメントはランタイムエラーで停止します。

文字を変換できない場合に、この文字に対して置換文字が使用されるか変換が失敗するかは、CPCVERR パラメータの設定によって異なります。 Windows、UNIX、および OpenVMS プラットフォームでは、Unicode からデフォルトコードページ(CP)への変換について ICU によって定義されたデフォルトの置換文字は、プロファイルパラメータ SUBCHAR を使用して変更できます。

このステートメントは、U データから UTF-8 フォーマットへの変換についても使用できます。

注意:
デフォルトコードページとは異なるコードページにデータを変換する場合は、このデータを I/O で使用しないことをお勧めします。 I/O は、デフォルトコードページでのみ意味があります。

EXAMINE

"grapheme" は、ユーザーが一般に文字と見なすものです。 ほとんどの場合、Unicode コードポイントは書記素ですが、書記素が複数の Unicode コードポイントで構成される場合もあります。 例えば、1 つの基底文字と 1 つ以上の結合文字のシーケンスは書記素です。

例:"a" (U+0061) + "." (U+0323) + "^" (U+0302) は、次のように表示される 1 つの書記素を定義します。

graphics/uni-a-grapheme.gif

注意:
基底文字/結合文字のシーケンスが正規化される場合、このことはシーケンスが常に合成済み文字によって置き換えられることを意味しません。すべての文字に合成済みフォーマットがあるわけではないためです。

"補助コードポイント" は、"U+10000" と "U+10FFFF" の間の Unicode コードポイントです。 補助コードポイントは UTF-16 であり、2 つのコード単位で構成されるサロゲートペアによって表されます。ペアの最初の値は "上位サロゲートコード単位"、2 番目は "下位サロゲートコード単位" です。 このような文字は一般的にはまれですが、中国語や日本語の人名の一部などで使用される場合があります。したがって、東アジアの国の行政アプリケーションでは、一般にこれらの文字のサポートが必要です。

EXAMINE とその SUBSTRING オプションなどの文字列操作ステートメントは、UTF-16 コード単位を処理します。 コードによって書記素またはサロゲートペアが分離されないようにすることは、ユーザーの責任です。

ただし、EXAMINE ステートメントの節 CHARPOSITION および CHARLENGTH(「構文 3 - Unicode 書記素用の EXAMINE」を参照)を使用して、書記素の UTF-16 コード単位での開始位置および長さを求めることができます。 結果の値は、SUBSTRING 呼び出しに使用できます。 これらの節を使用して、書記素ごとに文字列をスキャンできます。

例:

DEFINE DATA LOCAL
1 #UNICODE-STRING    (U15)
1 #CODE-UNIT-INDEX   (N4)
1 #CODE-UNIT-LEN     (N4)
1 #GRAPHEME-NUMBER   (N4)
END-DEFINE

MOVE U'graphics/uni-examine-grapheme.gif' TO #UNICODE-STRING

#GRAPHEME-NUMBER := 1

REPEAT
EXAMINE
        FULL VALUE OF #UNICODE-STRING
        FOR CHARPOSITION #GRAPHEME-NUMBER
        GIVING POSITION IN #CODE-UNIT-INDEX
        GIVING LENGTH IN #CODE-UNIT-LEN

        DISPLAY #UNICODE-STRING #GRAPHEME-NUMBER #CODE-UNIT-INDEX #CODE-UNIT-LEN

        #GRAPHEME-NUMBER := #GRAPHEME-NUMBER + 1
WHILE #CODE-UNIT-INDEX NE 0
END-REPEAT

END

上記のプログラム例の出力は、次のとおりです。

Page     1                                                   05-12-15  09:33:49

#UNICODE-STRING #GRAPHEME-NUMBER #CODE-UNIT-INDEX #CODE-UNIT-LEN
--------------- ---------------- ---------------- --------------

graphics/uni-examine-grapheme.gif           1                1                1
graphics/uni-examine-grapheme.gif           2                2                2
graphics/uni-examine-grapheme.gif           3                4                1
graphics/uni-examine-grapheme.gif           4                5                3
graphics/uni-examine-grapheme.gif           5                8                1
graphics/uni-examine-grapheme.gif           6                9                3
graphics/uni-examine-grapheme.gif           7               12                1
graphics/uni-examine-grapheme.gif           8               13                3
graphics/uni-examine-grapheme.gif           9                0                0

PARSE XML

XML 文書では、文書のエンコードに関する情報を XML 文書ヘッダーに含めることができます(例えば、<?xml version="1.0" encoding="UTF-8" ?>)。 XML 文書にこの情報が含まれている場合、Windows、UNIX、および OpenVMS プラットフォームでの XML 文書の解析には、受け取りフィールドがフォーマット U ではない場合は、XML 文書ヘッダー内で指定されたコードページから Natural のデフォルトコードページ(システム変数 *CODEPAGE の値)への変換が常に含まれます。

メインフレームプラットフォームでは、文書がすでに UTF-16 でエンコードされていない場合、解析される文書は常に内部的に UTF-16 に変換されます。

詳細については、PARSE XML ステートメントの説明を参照してください。

プログラミングガイド』の「インターネットおよび XML アクセス用のステートメント」も参照してください。

REQUEST DOCUMENT

REQUEST DOCUMENT ステートメントを使用したデータ転送では、通常、コードページ変換は呼び出されません。 送信データ/受信データを特定のコードページでエンコードする場合は、REQUEST DOCUMENT ステートメントの DATA ALL 節/RETURN PAGE 節を使用して指定できます。

詳細については、REQUEST DOCUMENT ステートメントの説明を参照してください。

プログラミングガイド』の「インターネットおよび XML アクセス用のステートメント」も参照してください。

DEFINE PRINTER

メインフレームプラットフォームでは、DEFINE PRINTER ステートメントに CODEPAGE 節があり、出力レポートデータをデフォルトコードページ(システム変数 *CODEPAGE の値)とは異なるコードページに変換できます。 Windows、UNIX、および OpenVMS プラットフォームでは、DEFINE PRINTER ステートメントにそのような節はありません。CODEPAGE 節が定義された場合、Windows、UNIX、および OpenVMS プラットフォームでは無視されます。

CALLNAT(RPC)

RPC 経由での Unicode フォーマットでのデータ交換がサポートされています。 CALLNAT ステートメントの説明を参照してください。

U データがビッグエンディアンエンコードのプラットフォームからリトルエンディアンエンコードのプラットフォームへ、またはその逆に送信される場合、エンコードは受信プラットフォームのエンコードに準拠するように変更されます。 例えば、リトルエンディアンエンコードの U データがビッグエンディアンのプラットフォームに到着した場合、このデータはビッグエンディアンエンコードに変換されてからプログラムに渡されます。 このデータが送り返されるときは、リトルエンディアンエンコードに戻されます。

Top of page

論理条件基準

論理条件基準では、Unicode のオペランドを英数字およびバイナリのオペランドとともに使用できます。 すべてのオペランドが Unicode のオペランド(フォーマット U)というわけではない場合は、2 番目以降のオペランドはすべて最初のオペランドのフォーマットに変換されます。 バイナリのオペランド(フォーマット B)が 2 番目以降のオペランドとして指定された場合、バイナリのオペランドの長さは偶数である必要があります。バイナリのオペランドには Unicode コードポイントが含まれていると想定されます。

最初のオペランドが Unicode のオペランド(フォーマット U)であるために、比較が Unicode 比較として実行される場合、ICU 照合アルゴリズムが使用されます。 ICU アルゴリズムでは、単純なバイナリ比較は実行されません。 そのため、例えば次のような結果になります。

注意:
英数字と Unicode のオペランドの比較は、フィールドのシーケンスに応じて、異なる結果となる場合があります。

プログラミングガイド』の「論理条件基準」も参照してください。

Top of page

システム変数

このセクションでは、次のトピックについて説明します。

*CODEPAGE

システム変数 *CODEPAGE は、デフォルトコードページ(Unicode とコードページフォーマット間の変換に使用されているコードページ)の IANA 名を返すために使用されます。

*LOCALE

システム変数 *LOCALE には、現在のロケールの言語および国が含まれています。

Top of page

ラージ変数およびダイナミック変数

U フォーマットは、ラージ変数およびダイナミック変数に使用できます。 ダイナミック U 変数の場合、*LENGTH によって UTF-16 コード単位の数が返されます。

プログラミングガイド』の「ダイナミック変数およびフィールドについて」も参照してください。

Top of page

セッションパラメータ

次のセッションパラメータを使用できます。

パラメータ 説明
DL フォーマット A または U のフィールドの表示長を指定します。 『プログラミングガイド』の「出力の表示長 - DL パラメータ」も参照してください。
EMU* Unicode での編集マスク
ICU* Unicode での挿入文字
LCU* Unicode での先頭文字
TCU* Unicode での末尾文字

上記の表でアスタリスク(*)マークが付いたセッションパラメータは、Windows、UNIX、および OpenVMS プラットフォームでのみ使用できます。

DLAL の比較

Natural が Unicode 対応ではなかった間は、英数字フィールドの長さは、フィールドを表示するために必要な列の数(表示列の数)と常に同じでした。 このことは、DBCS コードページを使用する東アジア言語についても該当しました。A フォーマットフィールドは、半分の文字のみを保持できます。例えば、A10 は A5 になります。

例:

DEFINE DATA LOCAL
1  #A8 (A8)
END-DEFINE                                   
#A8 := 'computer'
WRITE #A8
#A8 := 'graphics/uni-chinese-char.gif'
WRITE #A8
END

上のコードの出力結果は、次のとおりです。

Page      1 ...

computer
graphics/uni-chinese-char.gif

U フォーマットフィールドでは、フィールドの長さと表示列の数は同じではなくなります。 U の文字は、狭い幅(ラテン文字など)か、広い幅(中国語文字など)か、または幅を持たない(結合文字など)場合があります。 したがって、U フィールドが必要とする表示列の数はまったくわかりません。これは、フィールドの内容によって異なります。 Natural では、画面上に予約する必要がある列の数を自動的に決定できません。最大サイズを想定するとラテン出力で大きな差異が発生し、最小サイズを想定すると中国語出力が完全には表示されない場合があります。 したがって、Natural のプログラマは、フィールドの表示幅を定義する必要があります。これは、DL パラメータを使用して行います。 AL パラメータは、この目的には使用できません。このパラメータでは、フィールドの定義された長さを超える部分が切り取られるためです。 U フィールドから文字を切り取るのではなく、次のフィールドの開始位置のみを定義する必要があります。

例:

DEFINE DATA LOCAL
1  #U8 (U8)
1  #U4 (U4)
END-DEFINE                                   
#U8 := 'computer'
WRITE #U8
#U4 := U'graphics/uni-chinese-char.gif'
WRITE #U4 (DL=8)
END

上記のコードの結果は、前と同じ出力になります。

Page      1 ...

computer
graphics/uni-chinese-char.gif

Windows では、出力ウィンドウを使用してローカルで、または Natural Web I/O インターフェイスクライアントを使用してリモート開発環境で、DL パラメータに定義された値がフィールドの実際の表示幅よりも小さいフィールド内をスクロールできます。

EMUICULCUTCUEMICLCTC の比較

パラメータ EMUICULCU、および TCU(Windows、UNIX、および OpenVMS プラットフォームでのみ使用可能)を使用すると、デフォルトコードページに含まれていない文字を使用できます。 文字は、生成されたプログラムに Unicode フォーマットで保存されます。 これらのパラメータは、すべてのフィールドフォーマットで使用できます。

パラメータ EMICLC、および TC も、U フォーマットフィールドで使用できます。 デフォルトコードページに含まれている文字が他のコードページではエンコードが異なる場合に、これらのパラメータも便利な場合があります。 例えば、ユーロ記号(€)は、"windows-1252"(Latin 1)コードページではコードポイント "0x80" ですが、"windows-1251"(キリル語)コードページではコードポイント "0x88" です。 したがって、Unicode パラメータを使用することによって、PC にインストールされているコードページにかかわらず、ユーロ記号は常に正しく表示されるようになります。

EMU の例:

DEFINE DATA
LOCAL
 01 EMPLOYEES-VIEW VIEW OF EMPLOYEES
   02 FIRST-NAME
   02 NAME
   02 SALARY (1)
END-DEFINE
*
  READ (6) EMPLOYEES-VIEW
    DISPLAY NAME FIRST-NAME SALARY(1) (EMU=999,999graphics/uni-euro-sign.gif)
  END-READ
*
END

上のコードの出力結果は、次のとおりです。

Page     1                                                   05-12-15  11:45:36

        NAME              FIRST-NAME       ANNUAL
                                           SALARY
-------------------- -------------------- --------

ADAM                 SIMONE               159,980graphics/uni-euro-sign.gif 
MORENO               HUMBERTO             165,810graphics/uni-euro-sign.gif 
BLOND                ALEXANDRE            172,000graphics/uni-euro-sign.gif 
MAIZIERE             ELISABETH            166,900graphics/uni-euro-sign.gif 
CAOUDAL              ALBERT               167,350graphics/uni-euro-sign.gif 
VERDIE               BERNARD              170,100graphics/uni-euro-sign.gif

Top of page

サンプルプログラム

ライブラリ SYSEXPG に、Natural での Unicode およびコードページのサポートのサンプルプログラムがあります。

Top of page