我正在尝试创建一个自定义的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
确保get区域中至少有一个字符可用,std::filebuf
的有效实现将始终尝试将满缓冲区值的字符读入get区域。
我认为包装可能比扩展文件缓冲区更成功。
Boost iostreams使编写流过滤器变得简单得多。