Thread: streambuf

  1. #1
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034

    streambuf

    Okay, figures, I figure it out a few minutes after desperately asking for help. I'm still interested to know how to work with streams better and figure out their length instead of failing like original post. Also probably more correct way of doing this, since it's so very ugly, but works so I don't give a damn if that's the best I can get :P

    Code:
    std::vector<uint8_t> all;
    
    while(data.sgetc() != EOF)
    {
        all.push_back((uint8_t)data.sbumpc());
    }
    
    for(size_t i = 0, l = all.size(); i < l; ++i)
    {
        sprintf(ch, "\\x%02x", (uint8_t)all[i]);
    
        output += ch;
    
        data.sputc((uint8_t)all[i]);
    }
    ------ original post:

    This thing eludes me. I write to it, and have no problem reading it certain ways, but not others. What's most annoying is in_avail isn't working, and wrapped in istream tellg returns -1.

    asio::streambuf data; // just a wrapper for std::streambuf I belive
    I want to know the length so I can transverse the buffer without removing items, so I can print it in the correct format. Trying to print the stream as hex, eg. \x4C, and for some reason this doesn't work:

    Code:
    std::cout.setf(std::ios::hex | std::ios::showbase);
    According to the example and Google it's suppose to work, but it just shows sqaure boxes representing the bits to me. This works but only the first character:

    Code:
    std::cout << std::ios::hex << std::ios::showbase << &data << std::endl;
    This works because it doesn't rely on length..

    Code:
    std::vector<uint8_t> all;
    
    while(data.sgetc() != EOF)
    {
        all.push_back((uint8_t)data.sbumpc());
    }
    This is something I figured would work if I could ever get the correct length..

    Code:
    std::vector<uint8_t> all;
    
    data.pubseekoff(0, std::ios_base::begin);
    
    std::streamsize l = self->data.in_avail(); // 0
    
    for(size_t i = 0; i < l; ++i)
    {
        data.pubseekoff(i, std::ios_base::beg);
        
        all.push_back((uint8_t)data.sgetc());
    }
    Of course these work (off top of my head)..

    Code:
    std::istream data_stream(&data);
    
    std::string stuff((std::istreambuf_iterator<char>(data_stream)), std::istreambuf_iterator<char>());
    Code:
    std::istream data_stream(&data);
    
    std::string stuff;
    
    while(data_stream >> stuff) {}
    But this doesn't..

    Code:
    std::istream data_stream(&data);
    
    data_stream.seekg(0, std::ios::end);
    std::streamsize l = data_stream.tellg(); // -1
    data_stream.seekg(0, std::ios::beg);
    
    char buffer[l];
    
    data_stream.read(buffer, l);
    
    std::string all(buffer);
    
    data_stream.write(buffer, l);
    I could write a hundred different attempts and not get this...
    Last edited by Dae; 12-13-2009 at 06:57 AM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Trying to print the stream as hex, eg. \x4C, and for some reason this doesn't work:
    Consider the following:
    Code:
        char a = 'a';
        cout << hex << showbase << a << endl;
    You see 'a' because "hex" and "showbase" only affect integer ouput - not character output.
    What you need is this:
    Code:
        cout << hex << showbase << (unsigned)(unsigned char)a << endl;
    All the unsigned casting prevents sign extension.

    Not all stream buffers support the ability to seek. Also, not all stream buffers actually "buffer" anything - so in_avail() can legally return 0 even though sbumpc() may return a character.

    Think of a stream buffer as a "shim" between the "device" and the iostream object. So for example, a basic_filebuf<> sits between a real file and fstream object. When you go to read a single character, a naive basic_filebuf<> implementation would read a single character from the real file and send up that one character. Under that naive implementation, in_avail() is always 0.
    A real basic_filebuf<> may read in 512K bytes from the file, then send up the one byte requested. Now in_avail() would return 512K - 1, the amount in the buffer that's ready to be read without going back to the "device" for more.

    Having said all that, it seems that asio::basic_streambuf has additional semantics for playing with the buffer that it represents:
    http://www.boost.org/doc/libs/1_41_0...with_iostreams

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trying to override streambuf to use with cout
    By rob_l_f in forum C++ Programming
    Replies: 6
    Last Post: 01-12-2009, 01:31 AM
  2. How to read the contents of streambuf
    By vin_pll in forum C++ Programming
    Replies: 1
    Last Post: 07-28-2008, 05:26 AM
  3. problem with streambuf
    By vin_pll in forum C++ Programming
    Replies: 18
    Last Post: 06-22-2008, 04:13 AM
  4. Runtime error in streambuf
    By alvifarooq in forum C++ Programming
    Replies: 4
    Last Post: 11-06-2004, 07:31 PM
  5. Stupid compiler errors
    By ChrisEacrett in forum C++ Programming
    Replies: 9
    Last Post: 11-30-2003, 05:44 PM