Rogue Wave バナー
前へマニュアルの先頭へ目次次へ

19.2 例 1: 1 バイト文字変換の定義 (ASCII <-> EBCDIC)

ファイルストリームバッファとコード変換ファセットによる連携的な処理例として、EBCDIC で符号化されたテキストファイルを ASCII で符号化された文字ストリームに変換するための、コード変換ファセットの実装を紹介します。ASCII 文字と EBCDIC 文字の間の変換は、固定サイズの変換なので、文字はすべて 1 バイトで表します。そのため、変換は文字単位で行われます。

ASCII-EBCDIC コード変換ファセットを実装して使用するための手順は、次のとおりです。

  1. 標準コード変換ファセット型 codecvt から、新しいファセット型を派生させます。

  2. 文字型 char の新しいファセット型を特殊化します。

  3. バッファで使用するメンバー関数を実装します。

  4. ASCII-EBCDIC コード変換ファセットを持つロケールに、ファイルストリームのバッファを組み込みます。

次に、以上の手順の詳細を説明します。

19.2.1 新しいファセット型の派生

次に示すのは、新しいコード変換ファセット型 AsciiEbcdicConversion です。

template <class internT, class externT, class stateT>
class AsciiEbcdicConversion
: public codecvt<internT, externT, stateT>
{
};

文字型 char でクラステンプレートを特殊化するので、上記の型は空です。

19.2.2 新しいファセット型の特殊化とメンバー関数の実装

コード変換ファセットでは、2 つのメンバー関数 in()out() を使用します。

ファイルストリームバッファで使用する、コード変換ファセットの他のメンバー関数は次のとおりです。

ファセットの公開メンバー関数は、いずれも個別に限定公開の仮想メンバー関数 do_...() を呼び出します。次に示すのは、特殊化したファセット型の宣言です。

class AsciiEbcdicConversion<char, char, mbstate_t>
: public codecvt<char, char, mbstate_t>
{
protected:
 
 result do_in(mbstate_t& state
              ,const char* from, const char* from_end, const char*& from_next
              ,char* to        , char* to_limit      , char*& to_next) const;
 
 result do_out(mbstate_t& state
              ,const char* from, const char* from_end, const char*& from_next
              ,char* to        , char* to_limit      , char*& to_next) const;

 bool do_always_noconv() const thow()
 { return false; };
 
 int do_encoding() const throw();
 { return  1; }
 
};

簡潔にするために、ここでは、Rogue Wave のファイルストリームバッファの実装に使用する関数だけを実装します。さらに応用範囲の広いコード変換ファセットが必要な場合は、do_length()do_max_length() も実装してください。

関数 do_in()do_out() の実装は簡単です。どちらの関数も、[from,from_end) の範囲の文字シーケンスを対応するシーケンス [to,to_end) に変換します。ポインタ from_nextto_next は、正しく変換された最後の文字より後の位置を示します。基本的に、これらの関数に与える情報や結果に制限はありません。ただし、ファイルストリームバッファとの通信を有効にするには、処理結果の成功や失敗を正しく伝える必要があります。

19.2.3 新しいコード変換ファセットの使用

新しいコード変換ファセットの使用方法を、次に示します。

fstream inout("/tmp/fil");                                    //1
AsciiEbcdicConversion<char,char,mbstate_t> cvtfac;
locale cvtloc(locale(),&cvtfac);
inout.rdbuf()->pubimbue(cvtloc)                               //2
cout << inout.rdbuf();                                        //3
//1 ファイルを作成すると、デフォルトロケールとして、現在の大域ロケールのスナップショットが設定されます。ストリームには 2 つのロケールオブジェクトがあり、1 つは数値項目の書式設定に使用し、もう 1 つはストリームのバッファによるコード変換に使用します。
//2 ここで、ストリームバッファのロケールは、ASCII-EBCDIC コード変換ファセットを持つ大域ロケールのコピーに置き換えられます。
//3 EBCDIC ファイル "/tmp/fil" の内容が読み取られ、ASCII に自動的に変換され、cout に書き込まれます。

前へマニュアルの先頭へ目次次へ

Copyright (c) 1998, Rogue Wave Software, Inc.
このマニュアルに関する誤りのご指摘やご質問は、電子メールにてお送りください。


OEM リリース, 1998 年 6 月