mercredi 14 août 2019

C++ getline() with boost::iostreams::filtering_istream works strange

Please, help me to understand the reasons for the difference in the behavior of the following program under windows on MSVS 2017 on Windows and clang (online compiler). The program creates a test text file and a chain of boost filters (filtering_istream) from one source and one filter.

#include <iostream>
#include <fstream>
#include <string>
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/iostreams/filtering_stream.hpp>


class my_filter : public boost::iostreams::input_filter
{
public:
    explicit my_filter(std::ostream& s) : m_out(s)
    {}

    template<typename Source>
    int get(Source& src)
    {
        int c = boost::iostreams::get(src);
        if(c == EOF || c == boost::iostreams::WOULD_BLOCK)
            return c;

        if(c == '\r')
            return boost::iostreams::WOULD_BLOCK;

        if(c == '\n')
        {
            m_out << m_str << std::endl;
            m_str = "";
        }
        else
        {
            m_str += c;
        }
        return c;
    }
private:
    std::ostream& m_out;
    std::string m_str;
};


int main()
{
    using namespace std;
    boost::iostreams::filtering_istream file;
    const std::string fname = "test.txt";

    std::ofstream f(fname, ios::out);
    f << "Hello\n";
    f << "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\n";
    f << "World!\n";
    f.close();

    file.push(my_filter(std::cout));
    file.push(boost::iostreams::file_descriptor(fname));

    std::string s;
    while(std::getline(file, s))
    {}
    return 0;
}

Online compilation with clang displays the expected result:

enter image description here

The result of the program in windows:

enter image description here

But if change string "111...111" (127 ones) to 128 ones or 126 ones - everything starts to work correctly:

enter image description here

Note, than length of "111...111" string is 127 ones and this count may correlate with default buffer_size in boost::iostreams::filtering_istream::push method...

file.push(my_filter(std::cout), default_buf_size=...)

Aucun commentaire:

Enregistrer un commentaire