streambuf::xsgetn and state flags

This is what I found on libstdc++:

template<typename _CharT, typename _Traits>
streamsize basic_streambuf<_CharT, _Traits>::xsgetn(char_type* __s, streamsize __n) {
    streamsize __ret = 0;
    while (__ret < __n) {
        const streamsize __buf_len = this->egptr() - this->gptr();
        if (__buf_len) {
            const streamsize __remaining = __n - __ret;
            const streamsize __len = std::min(__buf_len, __remaining);
            traits_type::copy(__s, this->gptr(), __len);
            __ret += __len;
            __s += __len;
            this->__safe_gbump(__len);
        }

        if (__ret < __n) {
            const int_type __c = this->uflow();
            if (!traits_type::eq_int_type(__c, traits_type::eof())) {
                traits_type::assign(*__s++, traits_type::to_char_type(__c));
                ++__ret;
            } else
                break;
        }
    }
    return __ret;
}

When the characters extracted are less than the number of characters requested, this function calls uflow() to obtain more characters. If that function returns Traits::eof() then it will simply return whether or not 0 characters were extracted. The result of the function call is picked up by the higher-level stream operations that have access to the stream state, and will set it accordingly.

Leave a Comment