streambuf::xsgetn 和州旗
streambuf::xsgetn and state flags
受保护的虚拟成员函数 streambuf::xsgetn
使 I/O 流实现者能够定义一个函数,该函数从输入流中提取 n
个字符并将它们存储在缓冲区中。
通常,对于像 fstream
这样的大多数标准流,此函数只需在循环中调用 sbumpc
,直到 eof
被 returned。但是自定义流 class 可以覆盖此函数以执行更高效的操作,例如将数据批量复制到输出缓冲区。
但我不明白的是,xsgetn
如何指示已达到 EOF 条件。假设用户请求读取 100 个字节,但流中只剩下 50 个字节。据推测,xsgetn
应该读取 50 个字节,return 50
然后将内部流状态设置为 eof
。
除了xsget
是streambuf
的成员函数,它没有办法设置流状态。与 sbumpc
不同的是,它可以 return EOF
,xsgetn 无法指示 EOF 条件的发生。那么 xsgetn
应该如何处理 EOF 条件?
这是我在 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;
}
当提取的字符少于请求的字符数时,该函数调用uflow()
获取更多的字符。如果该函数 returns Traits::eof()
那么它只会 return 无论是否提取了 0 个字符。函数调用的结果由有权访问流状态的更高级别的流操作获取,并将相应地设置它。
受保护的虚拟成员函数 streambuf::xsgetn
使 I/O 流实现者能够定义一个函数,该函数从输入流中提取 n
个字符并将它们存储在缓冲区中。
通常,对于像 fstream
这样的大多数标准流,此函数只需在循环中调用 sbumpc
,直到 eof
被 returned。但是自定义流 class 可以覆盖此函数以执行更高效的操作,例如将数据批量复制到输出缓冲区。
但我不明白的是,xsgetn
如何指示已达到 EOF 条件。假设用户请求读取 100 个字节,但流中只剩下 50 个字节。据推测,xsgetn
应该读取 50 个字节,return 50
然后将内部流状态设置为 eof
。
除了xsget
是streambuf
的成员函数,它没有办法设置流状态。与 sbumpc
不同的是,它可以 return EOF
,xsgetn 无法指示 EOF 条件的发生。那么 xsgetn
应该如何处理 EOF 条件?
这是我在 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;
}
当提取的字符少于请求的字符数时,该函数调用uflow()
获取更多的字符。如果该函数 returns Traits::eof()
那么它只会 return 无论是否提取了 0 个字符。函数调用的结果由有权访问流状态的更高级别的流操作获取,并将相应地设置它。