Не вызывается "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 шт):
решил проблему тем, что в моей версии задавались границы ("setg()") в конструкторе, что и мешало корректной работе. нужно было добавить внутреннюю переменную для текущей позиции и работать с ней, вместо "gptr()"