私は既製のものを見つけることができなかったので、私は思いつきました:
class membuf : public basic_streambuf<char>
{
public:
membuf(char* p, size_t n) {
setg(p, p, p + n);
setp(p, p + n);
}
}
使用法:
char *mybuffer;
size_t length;
// ... allocate "mybuffer", put data into it, set "length"
membuf mb(mybuffer, length);
istream reader(&mb);
// use "reader"
stringstream
は知っていますが、指定された長さのバイナリデータを処理できないようです。
ここで自分のホイールを発明していますか?
[〜#〜]編集[〜#〜]
入力データが(テキストではなく)バイナリであり、そこからバイナリデータのチャンクを抽出するとします。入力データのコピーを作成せずにすべて。
boost::iostreams::basic_array_source
とboost::iostreams::stream_buffer
(from Boost.Iostreams )をboost::archive::binary_iarchive
(from Boost.Serialization )と組み合わせると、便利な抽出>>演算子を使用して、バイナリデータのチャンクを読み取ります。
#include <stdint.h>
#include <iostream>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/archive/binary_iarchive.hpp>
int main()
{
uint16_t data[] = {1234, 5678};
char* dataPtr = (char*)&data;
typedef boost::iostreams::basic_array_source<char> Device;
boost::iostreams::stream_buffer<Device> buffer(dataPtr, sizeof(data));
boost::archive::binary_iarchive archive(buffer, boost::archive::no_header);
uint16_t Word1, Word2;
archive >> Word1 >> Word2;
std::cout << Word1 << "," << Word2 << std::endl;
return 0;
}
AMD64のGCC 4.4.1では、次のように出力されます。
1234,5678
Boost.Serializationは非常に強力で、すべての基本的な型、文字列、さらにはSTLコンテナーをシリアル化する方法を知っています。型を簡単にシリアル化できます。ドキュメントを参照してください。 Boost.Serializationソースのどこかに隠されているのは、マシンのエンディアンの適切なスワッピングを実行する方法を知っているポータブルバイナリアーカイブの例です。これはあなたにも役立つかもしれません。
Boost.Serializationの空想を必要とせず、バイナリデータをfread()タイプの方法で読みたい場合は、basic_array_source
をより簡単な方法で使用できます。
#include <stdint.h>
#include <iostream>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
int main()
{
uint16_t data[] = {1234, 5678};
char* dataPtr = (char*)&data;
typedef boost::iostreams::basic_array_source<char> Device;
boost::iostreams::stream<Device> stream(dataPtr, sizeof(data));
uint16_t Word1, Word2;
stream.read((char*)&Word1, sizeof(Word1));
stream.read((char*)&Word2, sizeof(Word2));
std::cout << Word1 << "," << Word2 << std::endl;
return 0;
}
このプログラムでも同じ出力が得られます。
何が必要かわかりませんが、これで十分でしょうか?
char *mybuffer;
size_t length;
// allocate, fill, set length, as before
std::string data(mybuffer, length);
std::istringstream mb(data);
//use mb
標準のストリームバッファにはこの機能があります。
ストリームを作成します。バッファを取得してオーバーライドします。
#include <sstream>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
// Your imaginary buffer
char buffer[] = "A large buffer we don't want to copy but use in a stream";
// An ordinary stream.
std::stringstream str;
// Get the streams buffer object. Reset the actual buffer being used.
str.rdbuf()->pubsetbuf(buffer,sizeof(buffer));
std::copy(std::istreambuf_iterator<char>(str),
std::istreambuf_iterator<char>(),
std::ostream_iterator<char>(std::cout)
);
}
質問者はデータをコピーしない何かを望んでおり、彼の解決策はうまくいきます。私の貢献は少しクリーンアップすることなので、メモリ内のデータの入力ストリームである単一のオブジェクトを作成できます。私はこれをテストしましたが、うまくいきます。
class MemoryInputStream: public std::istream
{
public:
MemoryInputStream(const uint8_t* aData,size_t aLength):
std::istream(&m_buffer),
m_buffer(aData,aLength)
{
rdbuf(&m_buffer); // reset the buffer after it has been properly constructed
}
private:
class MemoryBuffer: public std::basic_streambuf<char>
{
public:
MemoryBuffer(const uint8_t* aData,size_t aLength)
{
setg((char*)aData,(char*)aData,(char*)aData + aLength);
}
};
MemoryBuffer m_buffer;
};