简体   繁体   中英

boost::iostreams reading from source device

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.

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM