2015-12-09 3 views
1

В Qt библиотеки там QByteArray и QDataStream классов, которые позволяют мне читать и писать переменные в Memmory буфер с очень простой в использовании синтаксиса:IStream для полукокса буфера

QByteArray data = getData(); 
QDataStream stream(data); 
double d = 0; 
int i = 0; 
stream >> d >> i; 

Как реализовать simmilar поведение только СТЛ поток классы? Например, у меня есть константный символ * данные и размер, так что я хочу построить зЬй :: IStream и читать varibles из этих данных:

const char* data = getData(); 
size_t size = getSize(); 

membuffer buf(data, data + size); 
std::istream str(buf); 
double d = 0; 
str >> d; 

Обратите внимание, что данные не должны быть скопированы!

+1

Классы 'std :: xstream' имеют функциональность' QTextStream', * not * 'QDataStream'. В стандартной библиотеке C++ нет ничего похожего на 'QDataStream'. Вообще говоря, 'std :: istream' будет бесполезным для вашей цели. Повторное выполнение 'QDataStream' [совсем не сложно] (http://stackoverflow.com/a/31687943/1329652). –

+0

Как только исправлены неверные предположения, это, возможно, дубликат [этого вопроса] (http://stackoverflow.com/q/31686553/1329652). –

+0

@KubaOber: при условии, что запрос должен был сделать что-то подобное, используя стандартные потоки, вопрос, на который вы указали (и тем более ответ), явно не отвечает ... –

ответ

0

Предполагая, что у вас есть фиксированного размера буфера данных и его размер тривиально реализовать путем создания подходящего потока буфера:

struct membuf: std::streambuf { 
    membuf(char* begin, char* end) { 
     this->setg(begin, begin, end); 
    } 
}; 

Этот простой буфер поток просто устанавливает поток буферов «получить-зону», чтобы диапазон [begin, end) (begin используется дважды, так как можно создать «область с обратной связью», которая в этом случае пуста). Когда больше нет символов для чтения потока, попробуйте вызвать underflow(), реализация по умолчанию которого указывает на сбой. Если вы хотите прочитать больше символов, вы должны перезаписать underflow(), чтобы предоставить больше символов в новом буфере настройки.

С, что вы можете создать поток с помощью этой памяти резервной копии буфера потока:

membuf  sbuf(begin, end); 
std::istream in(&sbuf); 
double d = 0; 
if (in >> d) { // always check conversions from string to a value... 
    // ... 
} 

Для немногих дополнительного удобства, создание буфера потока и потока также может быть объединено в класс. Существует маленькая хитрость в том, что буфер потока должен быть создан достаточно раньше, но это выполнимо:

class imemstream: private virtual membuf, public std::istream { 
public: 
    imemstream(char* begin, char* end) 
     : membuf(begin, end) 
     , std::ios(static_cast<std::streambuf*>(this)) 
     , std::istream(static_cast<std::streambuf*>(this)) { 
    } 
}; 

Просто предупреждение, хотя: создание потока является более дорогостоящим, чем копирование совсем немного данных. То есть, если вы хотите использовать этот поток в цикле, вы, вероятно, захотите предоставить функциональность для сброса буфера (возможно, в сочетании с флажками состояния очистки).

+0

'QDataStream' не имеет ничего общего с преобразованиями текста, хотя ... Это двоичный поток, используемый для двоичной сериализации, а не для сериализации текста. –

+0

@KubaOber: запрос должен считываться с 'std :: istream', используя' str >> d'. Это явно читает текстовые данные. –

+0

Kuba Ober is rigth Мне не нужно читать и писать по строкам, мне нужна двоичная десериализация. – Jeka

Смежные вопросы