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

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


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

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

  • フォーマット U
    フォーマット U を使用して、Unicode 文字列を保持するデータを定義できます。Natural データフォーマット U は、内部的には UTF-16 です。

    プログラミングガイド』の「ユーザー定義変数のフォーマットおよび長さ」も参照してください。

  • U 定数
    接頭辞 "U" を使用して、Unicode 定数を定義できます。例えば、次のようになります。

    U'Äpfel'

    接頭辞 "UH" は、Unicode 定数を 16 進形式で定義するために使用できます。Unicode 標準で定義されているように、4 桁の 16 進数は 1 つの UTF-16 コード単位を表します。したがって、全体の長さは 4 の倍数になります。例えば、次の 16 進形式が必要であるとします。

    U'Äpfel'

    "Ä"、"p"、"f"、"e"、および "l" の UTF-16 コード単位("U+00C4"、"U+0070"、"U+0066"、"U+0065" および "U+006C")が必要であり、これらを次の 16 進数の文字列に結合する必要があります。

    UH'00C4007000660065006C'

    プログラミングガイド』の「Unicode 定数」も参照してください。

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

U と A の比較

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

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

ステートメント

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

基本的に、A フォーマットと U フォーマットは 1 つのステートメントで一緒に使用できますが、1 つのステートメント内では A または U のいずれか 1 つのフォーマットのみを使用することをお勧めします。両方のフォーマットを一緒に使用する場合はすべての変数を統一フォーマットに変換する必要がありますが、これにより変換エラーが発生する可能性があります。

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 節での潜在的な変換エラーを取得する場合は、このステートメントを使用できます。この場合は、CPCVERRON に設定されている場合に、MOVE ステートメントはランタイムエラーで停止します。

文字を変換できない場合に、この文字に対して置換文字が使用されるか変換が失敗するかは、CPCVERR パラメータの設定によって異なります。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 の値)への変換が常に含まれます。

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

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

REQUEST DOCUMENT

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

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

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

CALLNAT(RPC)

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

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

論理条件基準

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

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

  • "U+0000" などの一部のコードポイントは、比較プロセスで無視されます。

  • 組み合わされた文字は、等価の 1 つのコードポイントと等しいとみなされます。例えば、"U+00E4" によって表されるドイツ語の文字 "ä" と、コードポイント "U+0061" および "U+0308" の組み合わせは、ICU によって等しいとみなされます。

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

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

システム変数

*CODEPAGE

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

*LOCALE

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

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

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

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

セッションパラメータ

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

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

DL と AL

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 パラメータに定義された値がフィールドの実際の表示幅よりも小さいフィールド内をスクロールできます。

EMU、ICU、LCU、TCU と EM、IC、LC、TC

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

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

サンプルプログラム

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

  • UNICOX01 は、すべての Unicode 文字をリストします。

  • UNICOX02 は、Unicode 文字をコードポイントに、またはその逆に変換します。

  • CODEPX01 は、すべてのコードページ、そのコードページが Natural でサポートされているかどうか、およびそのコードページが使用するエンコードをリストします。サポートされるすべてのコードページについて、そのコードページの文字をリストするサービスおよびコードページの文字列を 16 進表示に変換したり、その逆に変換したりするサービスを提供します。

  • CODEPXL1 は、任意の 1 バイトコードページのすべての文字をリストします。

  • CODEPXL2 は、任意の 2 バイトコードページのすべての文字をリストします。

  • CODEPXC1 は、任意のコードページの文字列を 16 進表示に、およびその逆に変換します。