Please, help me to understand the reasons for the difference in the behavior of the following program.
The program creates a test text file and a chain of boost filters (filtering_istream
) from one source and one filter. Then it tries to read some lines.
#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\r\n";
f << "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111\r\n";
f << "World!\r\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:
But if I change the string "111...111" (128 ones) to 127 ones (255 and so on), the result differs:
This behavior seems incorrect to me.
Note: the length of "111...111" (127 ones) correlates with default buffer_size in boost::iostreams::filtering_istream::push
method...
file.push(my_filter(std::cout), default_buf_size=...)
You may see and run code here: code_example
Update 1
I find it strange that under some conditions, the return value of WOULD_BLOCK
allows you to read further, and under other conditions, it considers that the file is finished. But according to documentation:
WOULD_BLOCK - indicates that input is temporarily unavailable
So it doesn’t indicate the end of stream.