4

iostreamストリームにオンザフライで書き込んだり、ストリームから読み取ったりするデータを変更できるアダプタクラスを作成したいと思います。アダプター自体は、iostreamサードパーティのコードに対して真の透過性を実現するためのものである必要があります。

StreamEncoderから派生したクラスの例std::ostream

// External algorithm, creates large amounts of log data
int foo(int bar, std::ostream& logOutput);

int main()
{
    // The target file
    std::ofstream file("logfile.lzma");
    // A StreamEncoder compressing the output via LZMA
    StreamEncoder lzmaEncoder(file, &encodeLzma);
    // A StreamEncoder converting the UTF-8 log data to UTF-16
    StreamEncoder utf16Encoder(lzmaEncoder, &utf8ToUtf16);

    // Call foo(), but write the log data to an LZMA-compressed UTF-16 file
    cout << foo(42, utf16Encoder);
}

私の知る限り、新しい派生物を作成してサブクラスにbasic_streambuf埋め込む必要がありますが、それはかなり複雑なようです。basic_ostream

これを達成するためのより簡単な方法はありますか?

4

1 に答える 1

4

奇妙なことに、少なくとも物事が実際に機能することを意図しているので、これのどれもiostreamsおよび/またはstreambufsを直接含むべきではありません。

iostreamはマッチメーカークラスだと思います。iostreamには、ある種の外部ソース/データのシンクへのバッファリングされたインターフェイスを提供するstreambufがあります。また、すべてのフォーマットを処理するロケールもあります。iostreamは、(いわば)これら2つをうまく一緒にプレイし続けるプレイグラウンドスーパーバイザーにすぎません。データのフォーマットを扱っているので、これはすべてロケールで処理されます(または処理される必要があります)。

ただし、ロケールはモノリシックではありません。ロケールはいくつかのfacetsで構成されており、それぞれがデータフォーマットの特定の部分に専念しています。この場合、おそらく気になる部分はcodecvtファセットです。ファセットは、iostreamから読み取られる/iostreamに書き込まれるデータの外部表現と内部表現の間を変換するために(ほぼ排他的に)使用されます。

ただし、良くも悪くも、ロケールには一度に1つのcodecvtファセットしか含めることができず、考えているようなそれらのチェーンを含めることはできません。そのため、本当に必要/必要なのは、外部インターフェイスとしてcodecvtを提供するラッパークラスですが、I/O中にデータに対して実行される任意の変換セットをチェーンすることができます。

utfからutfへの変換の場合、Boost.localeはutf_to_utf関数とcodecvtラッパーコードを提供するため、変換のこの部分を実行するのは簡単で簡単です。

誰もがそのようなことをICUで行うことを提案しないように、Boost.LocaleはICUのラッパーであるため、これはほぼ同じ答えですが、C ++にはるかに適した形式です(ICUに対して)それ自体はかなりJavaに似ており、C++に対して明らかに敵対的です。

もう1つの側面は、codecvtファセットを作成すると、かなり単純なタスクが非常に複雑になることです。フィルタリングstreambuf(一例)は、一般的に作成がはるかに簡単です。それでもあなたが望むほど簡単ではありませんが、codecvtファセットほど悪くはありません。@Flexoですでに述べたように、Boost iostreamsライブラリには、zip圧縮を行うフィルタリングstreambufがすでに含まれています。lzma(またはlzh、算術などの圧縮)でほぼ同じことを行うのは比較的簡単です。少なくとも、使いやすい圧縮関数があると仮定します(基本的には、入力のバッファーを提供するだけで、次のバッファーを提供します。結果)。

于 2012-07-15T20:19:35.777 に答える