streambuf для ifstream не возвращает последний блок данных - PullRequest
0 голосов
/ 03 октября 2019

Я реализую 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 байтов. Что я делаю не так?

...