Version: 2.9.4
wxMBConv の概要

クラス: wxMBConv, wxMBConvLibc, wxMBConvUTF7, wxMBConvUTF8, wxCSConv, wxMBConvUTF16, wxMBConvUTF32

wxMBConv クラスは Unicode を意識したアプリケーションにおいて、依然として使用されている様々な 8 ビットエンコーディングと Unicode との間の変換を簡単に行えるようにします。


背景: 変換に対する要件

プログラムがよりグローバル化し、かつてないほどユーザが国境を超えてドキュメントをやり取りするようになるにつれ、世界中で使用されているすべての文字コードについて考慮することがますます求められるようになりました。コンピュータが昔から使用しているデフォルトのバイト単位の文字コードに依存するだけではもう不十分です。

数年前にひとつの解決策が提案されました: それが Unicode 規格です。使用されている文字の一式をひとつの統一的な符号化システムに含めることができるため、これは文字コードに関する問題を完全に解決します。

しかし、これまでには存在しなかった、Unicode への移行という新たな課題が生じました。その結果、UTF-8 などの "互換エンコーディング" が考案されました。いまだに多くのシステムは旧来の 8 ビットエンコーディングに依存しており、膨大なレガシーコードがいまだに使用されていることがネックになっています。Unicode を意識したシステムから別のシステムへ Unicode データを送信するときでさえ、昔ながらの転送チャネル経由で制約を受けずにやり取りするために 8 ビットのマルチバイトエンコーディング (この目的には一般的に UTF-7 か UTF-8 が使用されます) に符号化する必要があります。

背景: wxString クラス

Todo:
この概要を書き直す; wxString の変更が反映されていない

wxWidgets を Unicode モードでコンパイルしている場合、wxChar 型は char ではなく wchar_t と等価になります。そして、wxString は wxChar を格納します。したがって、wxString に対するすべての操作は Unicode 文字列に対して行われます。これは普通の char 文字列を使用する場合とほぼ同じくらい簡単です。(wxT() マクロを使用してリテラル文字列を囲むことを覚えておく必要があるだけです)

しかし、Unicode 文字列を使用できない環境もよくあります。これはネットワーク越しにデータを送信する場合や他のアプリケーションで扱うテキストファイルを処理する場合です。取り扱いの簡単な Unicode データと伝統的な 8 ビットエンコーディングとを相互に変換する方法が欲しいと思うでしょう。そしてこれこそが wxMBConv クラスの行なうことです。

wxMBConv クラス

これらすべての変換の基底クラスが wxMBConv クラスです。(このクラス自身では標準 libc ロケールの変換を実装しています) 継承クラスには wxMBConvLibc、いくつかの wxMBConvUTFxxx クラス、wxCSConv が含まれており、それぞれ異なる種類の変換を行います。必要であれば、独自のエンコーディング用に継承クラスを作成して使用することも可能です。必要なことは MB2WC 関数と WC2MB 関数をオーバーライドすることだけです。

wxMBConv オブジェクト

wxWidgets の提供する wxMBConv クラスのうち、いくつかのクラスは事前に定義されたインスタンスを持っています。(wxConvLibc、wxConvFileName、wxConvUTF7、wxConvUTF8、wxConvLocal) これらの事前定義されたオブジェクトを直接使用することもできますし、それとは別にインスタンス化することもできます。

wxConvCurrent 変数は (GTK+ 1.2 のように) ユーザインタフェースが Unicode ベースでない場合に、ユーザインタフェースで使用する変換オブジェクトを指しています。デフォルトでは wxConvLibc と wxConvLocal のうち、現在のプラットフォームに適している方が使用されます。

wxCSConv

wxCSConv クラスは特別なクラスです。なぜなら、インスタンス化するときに使用する文字コードを指定することができるためです。このことは異なる文字コードのインスタンスを多数保持する場合に意味があります。(もしくは実行時に wxCSConv のインスタンスを作成することができます)

事前に定義された wxCSConv インスタンスである wxConvLocal はデフォルトのユーザ文字コードを使用するように設定されていますが、これを直接使用する必要はほとんどなく、それよりも wxConvCurrent を使用するべきです。

文字列の変換

変換に使用したいオブジェクトを選択したら、それらを wxString と一緒に使用する方法を以下に示します。これらのサンプルはどれも wxWidgets の Unicode ビルドを使用していると仮定していますが、非 Unicode ビルドでもコンパイルすることは可能です。(その場合、何も変換されないだけです)

例 1: 現在のエンコーディングの入力から wxString を構築する。

wxString str(input_data, *wxConvCurrent);

例 2: UTF-8 の入力。

wxString str(input_data, wxConvUTF8);

例 3: KOI8-R の入力。実行時における wxCSConv インスタンスの構築。

wxString str(input_data, wxCSConv(wxT("koi8-r")));

例 4: wxString を標準出力へ UTF-8 で出力する。

puts(str.mb_str(wxConvUTF8));

例 5: wxString を標準出力へ任意のエンコーディングで出力する事前に構築した wxCSConv インスタンスを使用する。

wxCSConv cust(user_encoding);
printf("Data: %s\n", (const char*) str.mb_str(cust));
注:
mb_str() は変換結果を保持する一時 wxCharBuffer を返却するため、(printf のような) 可変数引数の関数を使用する場合は明示的に const char* にキャストする必要があります。

バッファの変換

特別な要件がある場合、もしくは単に wxString を使用したくない場合は変換オブジェクトの変換関数を直接使用することも可能です。これは非 Unicode ビルド版の wxWidgets で変換を行なう必要がある場合に役立ちます; UTF-8 から現在のエンコーディングへの変換はおそらくこのように行われます:

wxString str(wxConvUTF8.cMB2WC(input_data), *wxConvCurrent);

ここで、UTF-8 オブジェクトの cMB2WC は Unicode 文字列を含む wxWCharBuffer を返却します。そして、wxString のコンストラクタは引数に指定された変換オブジェクト、つまり *wxConvCurrent を使用して 8 ビット文字コードへ文字列を変換し直します。(Unicode ビルド版の wxWidgets の場合、コンストラクタは引き渡された変換オブジェクトを無視し、Unicode データのまま保持します)

これは元データの wxString を最初に作成するときにも行われます。

wxString input_str(input_data);
wxString str(input_str.wc_str(wxConvUTF8), *wxConvCurrent);

wxChar バッファを非 Unicode 標準出力へ出力するには次のようにします:

printf("Data: %s\n", (const char*) wxConvCurrent->cWX2MB(unicode_data));

変換後のデータに対してより複雑な処理を行なう必要がある場合、一時バッファをローカル変数に格納したいと思うかもしれません。

const wxWX2MBbuf tmp_buf = wxConvCurrent->cWX2MB(unicode_data);
const char *tmp_str = (const char*) tmp_buf;
printf("Data: %s\n", tmp_str);
process_data(tmp_str);

cWX2MB で変換が行われる場合 (つまり、Unicode ビルドの場合)、tmp_buf がスコープから外れると直ちにバッファが解放されます。(wxWX2MBbuf マクロは const でないことを除いて、cWX2MB の戻り値 (char* または wxCharBuffer) と同じ型になります)

 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines