Не вызывается "uflow()" в переопределении методов "std::streambuf"

почему этот код работает некорректно? основная идея в том, чтобы разрешать символы только из 'allowed_chars_' - но это просто не работает. я пытался всеми способами вызвать 'uflow()' - но не в какую он не хочет вызываться, даже насильно. логику в 'underflow()' реализовать не нужно! ее нужно сделать в других методах, а 'underflow()' должен вызывать/возвращать символ без изменений позиции (но вызов метода 'uflow()' допускается). 'xsgetn()' к слову, работает корректно (это метод '.read()')

код:

class FilterStreamBuffer : public std::streambuf {
private:
    std::string       buffer_;
    std::string_view  allowed_chars_;

    char_type current_char_ = traits_type::eof();

    // -- predict

    bool is_allowed(const char c) const {
        return allowed_chars_.find(c) != std::string::npos;
        // found = allowed
    }

protected:

    // -- underflow

    int_type underflow() override {
        if (int_type current_c = uflow(); current_c != traits_type::eof()) {
            return current_c;
        }
        return traits_type::eof();
    }

    // -- uflow

    int_type uflow() override {
        while (gptr() < egptr()) {
            current_char_ = traits_type::to_char_type(*gptr());
            gbump(1); // shift position

            if (is_allowed(current_char_)) {
                return traits_type::to_int_type(current_char_);
            }
        }
        return traits_type::eof();
    }

    // -- xsgetn

    std::streamsize xsgetn(char* str, std::streamsize count) override {
        std::streamsize read_count = 0;

        while (gptr() != egptr()) {
            current_char_ = *gptr();
            gbump(1);

            if (!is_allowed(current_char_)) {
                continue;
            }

            str[read_count++] = current_char_;
        }
        return read_count;
    }

public:
    explicit FilterStreamBuffer(std::string_view buffer, std::string_view allowed_chars) :
        buffer_(buffer), allowed_chars_(allowed_chars) {
        setg(buffer_.data(), buffer_.data(), buffer_.data() + buffer_.size());
    }

    // -- other

    std::string buffer() const {
        return buffer_;
    }
};

p.s. вот такой тест в 'main' работает некорректно:

FilterStreamBuffer buf("Hello, World! 123", "123 H");

std::istream is(&buf);
std::string result;

std::getline(is, result); // чтение строки полностью
std::cout << result << std::endl;

с таким кодом в 'main' должно вывести (пробелы включительно):

H  123

Ответы (1 шт):

Автор решения: user601192

решил проблему тем, что в моей версии задавались границы ("setg()") в конструкторе, что и мешало корректной работе. нужно было добавить внутреннюю переменную для текущей позиции и работать с ней, вместо "gptr()"

→ Ссылка