Подтвердить что ты не робот

Создание входного потока из постоянной памяти

У меня есть некоторые данные в буфере, на который указывает указатель 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 без копирования данных.)

4b9b3361

Ответ 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) для создания собственного класса потока, который читается из постоянной памяти.

Это не так просто, как кажется, потому что классы потока стандартной библиотеки С++ довольно грязны и плохо разработаны. Я не думаю, что это стоит того, если вам не нужно много масштабировать.