Создание входного потока из постоянной памяти
У меня есть некоторые данные в буфере, на который указывает указатель const char*
. Данные - это всего лишь строка ASCII. Я знаю его размер. Я хотел бы иметь возможность читать его так же, как данные считываются из потоков. Я ищу решение, которое позволит мне написать такой код:
// for example, data points to a string "42 3.14 blah"
MemoryStreamWrapper in(data, data_size);
int x;
float y;
std::string w;
in >> x >> y >> w;
Важное условие: данные нельзя копировать или изменять каким-либо образом (в противном случае я бы просто использовал поток строк. Насколько мне известно, невозможно создать поток строк из указателя const char без копирования данных.)
Ответы
Ответ 1
Способ сделать это - создать подходящий буфер потока. Это можно, например, сделать следующим образом:
#include <streambuf>
#include <istream>
struct membuf: std::streambuf {
membuf(char const* base, size_t size) {
char* p(const_cast<char*>(base));
this->setg(p, p, p + size);
}
};
struct imemstream: virtual membuf, std::istream {
imemstream(char const* base, size_t size)
: membuf(base, size)
, std::istream(static_cast<std::streambuf*>(this)) {
}
};
Единственное, что неудобно, это const_cast<char*>()
в буфере потока: буфер потока не будет изменять данные, но интерфейс по-прежнему требует использования char*
, в основном для облегчения изменения буфера в "обычных" потоковых буферов. При этом вы можете использовать imemstream
как обычный поток ввода:
imemstream in(data, size);
in >> value;
Ответ 2
Единственный способ заключается в подклассе std:: istream (который также требует подкласса std:: streambuf) для создания собственного класса потока, который читается из постоянной памяти.
Это не так просто, как кажется, потому что классы потока стандартной библиотеки С++ довольно грязны и плохо разработаны. Я не думаю, что это стоит того, если вам не нужно много масштабировать.