c++ - 自定义 std::fstream、std::filebuf 的上溢和下溢函数不会为每个字符调用
问题描述
我正在尝试制作一个自定义的 std::fstream,它会在读取时对数据进行编码/解码。
template <class T>
class _filebuf : public std::filebuf {
public:
using transform_type = T;
int_type underflow() override {
auto c = std::filebuf::underflow();
return c < 0 ? c : transform.decode(c);
}
int_type overflow(int_type c) override {
return c < 0 ? c : std::filebuf::overflow(transform.encode(c));
}
private:
transform_type transform;
};
template <class T>
class _fstream : public std::iostream {
public:
using buffer_type = _filebuf<T>;
explicit _fstream(const std::string& path, std::ios::openmode openmode)
: std::iostream(0)
{
this->init(&buffer);
buffer.open(path, openmode);
}
private:
buffer_type buffer;
};
这是一个用法示例:
class _transform {
public:
template <class T>
T encode(T value) const {
return value - 1;
}
template <class T>
T decode(T value) const {
return value + 1;
}
};
int main() {
_fstream<_transform> ofs("test.txt", std::ios::out | std::ios::trunc);
ofs << "ABC"; // outputs "@BC" to the file (@ is 64 in ASCII, so only first character encoded properly)
_fstream<_transform> ifs("test.txt", std::ios::in);
std::string s;
ifs >> s; // inputs "ABC" when "@BC" was in the file so again only first character is decoded
// ...
};
经过我自己的研究,我发现“溢出”函数在该过程中被调用了两次(使用65 和 -1,其中 -1 可能是 EOF),并且“下溢”也被调用了两次(使用64 和 -1)。由于其他字符不会丢失,因此它们可能会以某种方式在不调用这些函数的情况下进行处理。
为什么会发生这种情况以及如何改变它?
解决方案
std::streambuf<CharT,Traits>::underflow
确保在 get 区域中至少有一个字符可用,一个有效的实现std::filebuf
将始终尝试将一个完整的缓冲区值读取到 get 区域中。除非您寻求流underflow
不会再次被调用,直到 get 区域被调用清空sgetn
/xsgetn
或sbumpc
我认为您可能会更成功地包装而不是扩展文件缓冲区。
Boost iostreams使编写流过滤器变得更加简单。
推荐阅读
- json - Scala - 将 Map 转换为 Json 避免键/值关键字
- python - 检查两个对象是否属于一个特定类的规范方法是什么
- javascript - 试图理解这个 JavaScript 重复删除算法中的 for 循环
- haskell - Set value of record field to calculation involving another field in same record
- reactjs - 将我的静态网站的 AWS 给定域更改为 godaddy 域
- angular - 如何为版本 7 更新 Angular 项目版本 5
- fortran - 如何将包含字符串的文本文件读入Fortran中的数组
- python - 如何仅获取与模式匹配的文件名
- swift - 视频缩略图被颠倒了
- sql-server - 我无法让我的 Microsoft SQL Server 触发器正常运行