0

codecvtICU を使用してファセットを実装し、(ICU がサポートする) 文字エンコーディングを内部的に UTF-8 に変換したいと考えています。が存在し、この例codecvt_bynameに示すように、必要なことの一部を実行するために使用できることを認識しています。その例の問題点は、(1) ワイド文字ストリームを使用する (「通常の」バイト指向ストリームを使用したい) ことと、(2) 変換を実行するために 2 つのストリームが必要なことです。代わりに、次のような単一のストリームが必要です。

locale loc( locale(), new icu_codecvt( "ISO-8859-1" ) );
ifstream ifs;
ifs.imbue( loc );
ifs.open( "/path/to/some/file.txt" );
// data read from ifs here will have been converted from ISO-8859-1 to UTF-8

したがって、このような実装を行いたいのですが、ではなく ICU を使用しiconvます。それを考えると、私の実装do_in()は次のとおりです。

icu_codecvt::result icu_codecvt::do_in( state_type &state,
                                        extern_type const *from, extern_type const *from_end,
                                        extern_type const *&from_next, intern_type *to,
                                        intern_type *to_end, intern_type *&to_next ) const {
  from_next = from;
  to_next = to;
  if ( always_noconv_ )
    return noconv;

  our_state *const s = state_store_.get( state );
  UErrorCode err = U_ZERO_ERROR;
  ucnv_convertEx(
    s->utf8_conv_, s->extern_conv_, &to_next, to_end, &from_next, from_end,
    nullptr, nullptr, nullptr, nullptr, false, false, &err
  );
  if ( err == U_TRUNCATED_CHAR_FOUND )
    return partial;
  return U_SUCCESS( err ) ? ok : error;
}

our_stateオブジェクトは 2 つのポインタを保持しますUConverter*。1 つは「外部」エンコーディング (この例では ISO-8859-1) 用で、もう 1 つは UTF-8 エンコーディング用です。

私の質問は次のとおりです。

  1. nullptr上記のように「ピボット」バッファを指定する必要がありますか、それとも独自のものを提供する必要がありますか?
  2. reset引数 (現在はfalse上記の最初のもの) を に設定する必要がある場合はいつになるかわかりませんtrue
  3. flush引数 (現在はfalse上の 2 番目) をに設定するタイミングをtrueどのように知るか、つまり、入力の最後に到達したタイミングをどのように知るかは明確ではありません。

少しの援助?

4

1 に答える 1

0

codecvtファセットは、異なるエンコーディング間で変換することを目的としていません。代わりに、1つの文字が複数の外部単語(通常はバイト)を使用してエンコードされる可能性のある外部エンコードから、各文字が正確に1つの単語(char、wchar_t、char16_tなど)で表される内部表現に変換されます。

この観点から、内部文字シーケンスを「終了」することは意味がありません。使用可能な外部ワードがこれ以上ない場合、変換が実行され、最後の文字が不完全なままである場合、これは転送のエラーです。したがって、変換が完了したことを示す必要はなく、それに応じてインターフェイスもありません。これにより、「フラッシュ」引数は実際には常に「偽」である必要があることが明確になります。

UTF-8は、1つの単語で1つの文字を表すという法案に完全には適合しないことに気付きました。ただし、これは、標準タイプの処理文字列を使用したUTF-8処理に悩まされます。ただし、syringの変更を避けている限り、通常は問題なく機能します。

「リセット」パラメータは、おそらくストリーム内のシークを処理することを目的としています。filebufは、シーク時に新しいstate_typeオブジェクトを提供することになっていると思います。これはおそらく、ICU内部がリセットされることを望んでいることを示しています。しかし、私はICUインターフェースについて知りません。したがって、ピボットバッファを提供するかどうかもわかりません。

于 2011-12-30T17:40:22.607 に答える