boost::iostreams чтение с исходного устройства

Я пытался обойти мою библиотеку iostreams с помощью буста.

Но я не могу полностью понять концепции.

Скажем, у меня есть следующий класс:

Псевдокод: приведенный ниже код предназначен только для иллюстрации проблемы.

Редактировать: удалил код чтения, потому что он снял фокус на реальную проблему.

class my_source {
public:
    my_source():value(0x1234) {}
    typedef char        char_type;
    typedef source_tag  category;

    std::streamsize read(char* s, std::streamsize n)
    {
      ... read into "s" ...
    }
private:
    /* Other members */
};

Теперь скажите, что я хочу передать это int.

Что мне нужно сделать? Я пробовал следующее

boost::iostreams::stream<my_source> stream;
stream.open(my_source());

int i = 0;
stream >> i;
// stream.fail() == true; <-- ??

Это приводит к сбою, (failbit установлен)

Пока следующее работает отлично.

boost::iostreams::stream<my_source> stream;
stream.open(my_source());

char i[4];
stream >> i;    
// stream.fail() == false;

Может ли кто-нибудь объяснить мне, почему это происходит? Это потому что я установил char_type char?

Я не могу найти хорошее объяснение в любом месте. Я пытался прочитать документацию, но я не могу найти определенное поведение для char_type, если это проблема. Хотя, когда я использую stringstream, я могу читать в int, не делая ничего особенного.

Так что, если у кого-то есть понимание, пожалуйста, просветите меня.

2 ответа

Все iostreams являются текстовыми потоками, так что это будет принимать байтовое представление 0x1234, интерпретировать его как текст и пытаться проанализировать его как целое число.

Кстати

std::streamsize read(char* s, std::streamsize n)
{
  int size = sizeof(int);
  memcpy(s, &value, 4);
  return size;
}

Это может привести к переполнению буфера, если n < 4, Кроме того, вы пишете четыре байта, а затем возвращаете размер типа int. memcpy(s, &value, sizeof value); сделаю работу, простой return sizeof value; сделает все остальное

Конструктор boost::iostreams::stream без аргументов ничего не делает и в результате поток не открывается. Вам нужно добавить ложный аргумент в конструктор my_source.

class my_source {
public:
    my_source(int fake) : value(0x1234) {}
...

boost::iostreams::stream<my_source> stream(0);
Другие вопросы по тегам