ライブラリから受け取ったchar*とデータ長があり、istreamを受け取る関数にデータを渡す必要があります。
文字列ストリームを作成できることはわかっていますが、それによってすべてのデータがコピーされます。また、データはzipファイルであるため、必ず0になります。文字列ストリームを作成すると、最初の0までデータが取得されると思います。
すべてのデータをコピーせずにchar*とそのサイズからistreamを作成する方法はありますか?
Web で見つかった非推奨のメソッドを次に示します。独自のstd::streambuf
クラスを派生させますが、簡単で機能するようです。
#include <iostream>
#include <istream>
#include <streambuf>
#include <string>
struct membuf : std::streambuf
{
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};
int main()
{
char buffer[] = "I'm a buffer with embedded nulls\0and line\n feeds";
membuf sbuf(buffer, buffer + sizeof(buffer));
std::istream in(&sbuf);
std::string line;
while (std::getline(in, line)) {
std::cout << "line: " << line << "\n";
}
return 0;
}
どの出力:
line: I'm a buffer with embedded nullsand line
line: feeds
Boostを使用した非推奨のソリューション:
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/array.hpp>
using namespace boost::iostreams;
basic_array_source<char> input_source(my_ptr_to_char, byte_count);
stream<basic_array_source<char> > input_stream(input_source);
またはさらに簡単:
#include <boost/interprocess/streams/bufferstream.hpp>
using namespace boost::interprocess;
bufferstream input_stream(my_ptr_to_char, byte_count);
唯一の(単純な)ポータブルな方法には、コピーの作成が含まれます。
std::istringstream ss(std::string(buf,len));
実際、これにより、データが2回コピーされる可能性があります。1回はを作成するため、string
もう1回はを作成するためistringstream
です。(多分C ++ 11はmoveコンストラクターを介してコピーの1つを回避できます;私にはわかりません。)
ただし、運が良ければ、C++実装で次のことが可能になります。
std::istringstream ss;
ss.rdbuf()->pubsetbuf(buf,len);
GNU C ++(および他のいくつかの実装)では、これによりデータをコピーせずに文字列ストリームが作成されます。ただし、これは仕様によると「実装定義」の動作です。(この質問も参照してください。)
パラメータを含めることによりlen
、これらの両方がヌル文字で問題がないことを保証します。
必要なことを実行するための唯一の移植可能な方法は、独自のサブクラスを実装し、stringbuf
それを使用して文字列ストリームを初期化することです。心の弱い人のためではありません。
std :: istrstreamを試しましたか? http://stdcxx.apache.org/doc/stdlibref/istrstream.html
技術的には、非推奨だと思いますが、それでも標準の一部です。
Boost.Iostreams 配列のソース クラスとシンク クラスを試してください。
http://www.boost.org/doc/libs/1_47_0/libs/iostreams/doc/index.html