0
votes

I've been trying to get my head around the iostreams library by boost.

But i cant really fully grasp the concepts.

Say i have the following class:

Pseudocode: The below code is only to illustrate the problem.

Edit: removed the read code because it removed focus on the real problem.

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 */
};

Now say i want to stream the this to an int.

What do i need to do ? I've tried the following

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

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

This results in a fail, (failbit is set)

While the following works fine.

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

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

Could someone explain to me why this is happening ? Is this because i've set the char_type char ?

I cant really find a good explenation anywhere. I've been trying to read the documentation but i cant find the defined behavior for char_type if this is the problem. While when im using stringstreams i can read into a int without doing anything special.

So if anyone has any insight please enlighten me.

2

2 Answers

0
votes

All iostreams are textual streams, so this will take the bytewise representation of 0x1234, interpret it as text and try to parse it as integer.

By the way

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

This has the potential for a buffer overflow if n < 4. Also, you write four bytes and then return the size of an int. memcpy(s, &value, sizeof value); will do the job, a simple return sizeof value; will do the rest.

0
votes

boost::iostreams::stream constructor without arguments does nothing and in result stream is not open. You need to add fake argument to my_source constructor.

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

boost::iostreams::stream<my_source> stream(0);