Я реализую streambuf для пользовательского ifstream, который будет декодировать данные. Он оборачивает std :: ifstream и когда преобразует прочитанные данные с помощью пользовательского класса предиката. 'sink_' - это потоковый поток std :: ifstream.
class align_streambuf :
public std::basic_streambuf<Elem, Tr>
{
public:
align_streambuf( std::streambuf* sink, size_t buffer_size, Transform&& transform ) : sink_( *sink ), m_buffer( buffer_size, 0 ), buffer_size_( buffer_size ), transform_( std::move( transform ) )
{
// Input buffer
this->setg( &(m_buffer[0]), &(m_buffer[m_buffer.size()-1]), &(m_buffer[m_buffer.size() - 1]) );
};
int underflow()
{
size_t read = sink_.sgetn( &m_buffer[0] , buffer_size_ );
if( read )
{
transform_.transform( m_buffer, read );
this->setg( &(m_buffer[0]), &(m_buffer[0]), &(m_buffer[0]) + read );
} else
{
return std::ifstream::traits_type::eof();
}
return std::ifstream::traits_type::to_int_type( *this->gptr() );
}
....
private:
Transform transform_;
std::streambuf& sink_;
std::vector<char> m_buffer;
uint64_t buffer_size_;
Проблема, которую я не могу решить, это последнее чтение. Когда я читаю файл, последний не полный кусок данных просто не приходит.
XTSDecoder xtsDecoder( key.c_str() );
align_ifstream<XTSDecoder, 1024> stream2( "test.txt", std::move( xtsDecoder ) );
char data2[3000];
while( stream2.read( data2, 3000 ) )
{
std::cout << "Read: " << stream2.gcount() << std::endl;
}
Таким образом, если размер файла составляет 13000 байт, я получаю полные 12000 байт, и все последовательные операции чтения возвращаются0. Я получаю вызов undeflow для последних 1000 байтов, я вижу, что для него вызывается transform, и setg вызывается с правильным смещением. Но по какой-то причине read () возвращает 0 байтов. Что я делаю не так?