私はiostreamのバイナリバージョンを書いています。基本的に、バイナリ ファイルを書き込むことができますが、ファイルの形式を細かく制御できます。使用例:
my_file << binary::u32le << my_int << binary::u16le << my_string;
my_int を符号なし 32 ビット整数として書き込み、my_string を長さのプレフィックス付き文字列 (プレフィックスは u16le) として書き込みます。ファイルを読み戻すには、矢印を反転させます。よく働く。しかし、私はデザインに問題があり、それについてはまだ迷っています。だから、SOに尋ねる時が来ました。(現時点では、8 ビット バイト、2 の補数の整数、IEEE 浮動小数点数など、いくつかの仮定を立てています。)
内部では、iostream は streambuf を使用します。これは実に素晴らしい設計です。iostreams は ' int
' をテキストにシリアライズするコードを作成し、基になる streambuf に残りを処理させます。したがって、cout、fstream、stringstream などを取得します。これらはすべて、iostream と streambuf の両方で、通常は char でテンプレート化されますが、wchar としてテンプレート化されることもあります。ただし、私のデータはバイト ストリームであり、' unsigned char
' で表すのが最適です。
私の最初の試みは、に基づいてクラスをテンプレート化することでしたunsigned char
。std::basic_string
テンプレートで十分ですが、そうでstreambuf
はありません。という名前のクラスでいくつかの問題に遭遇しましたが、これはテーマcodecvt
に従うことができませんでした。unsigned char
これにより、次の 2 つの疑問が生じます。
1)なぜストリームバッファがそのようなことをするのですか? コード変換は、ストリームバッファの責任から外れているようです-ストリームバッファはストリームを取り、それとの間でデータをバッファリングする必要があります。これ以上何もない。コード変換と同じくらい高レベルなものは、iostream に属するべきだと感じます。
テンプレート化されたストリームバッファを unsigned char で動作させることができなかったので、char に戻り、単に char/unsigned char の間でデータをキャストしました。明らかな理由から、キャストの数を最小限に抑えようとしました。ほとんどのデータは、基本的に read() または write() 関数にまとめられ、その後、基になる streambuf が呼び出されます。(そして、プロセスでキャストを使用します。)読み取り関数は基本的に次のとおりです。
size_t read(unsigned char *buffer, size_t size)
{
size_t ret;
ret = stream()->sgetn(reinterpret_cast<char *>(buffer), size);
// deal with ret for return size, eof, errors, etc.
...
}
良い解決策、悪い解決策?
最初の 2 つの質問は、さらに情報が必要であることを示しています。最初に、boost::serialization などのプロジェクトが検討されましたが、それらは独自のバイナリ形式を定義するという点で、より高いレベルに存在します。これは、形式を定義する必要がある場合、または形式が既に定義されている場合、または一括メタデータが不要または不要な場合に、より低いレベルで読み取り/書き込みを行うためのものです。
binary::u32le
第二に、修飾子について質問する人もいます。これは、現時点では必要なエンディアンと幅を保持するクラスのインスタンス化であり、将来的には符号付きになる可能性があります。ストリームは、そのクラスの最後に渡されたインスタンスのコピーを保持し、それをシリアル化で使用しました。これはちょっとした回避策でした。最初は << 演算子を次のようにオーバーロードしようとしました。
bostream &operator << (uint8_t n);
bostream &operator << (uint16_t n);
bostream &operator << (uint32_t n);
bostream &operator << (uint64_t n);
しかし、当時、これはうまくいかなかったようです。あいまいな関数呼び出しでいくつかの問題がありました。これは特に定数に当てはまりますが、あるポスターが示唆したように、キャストするか、単に . として宣言することもできconst <type>
ます。しかし、他にも大きな問題があったことを覚えているようです。