Я пытался обойти мою библиотеку 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_type, если это проблема. Хотя, когда я использую stringstream, я могу читать в int, не делая ничего особенного.
Так что, если у кого-то есть понимание, пожалуйста, просветите меня.
Все 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);