使用自定义源提升 iostream zlib_error
Boost Iostreams zlib_error with Custom Source
我正在尝试使用zlib_decompressor
通过istreambuf_iterator
解压缩数据。我找不到使用输入迭代器作为流输入的内置方式(如果已经存在,请指出一种方法),所以我写了这个源代码:
template <class cha_type, class iterator_type>
class IteratorSource {
public:
typedef cha_type char_type;
typedef boost::iostreams::source_tag category;
iterator_type& i;
iterator_type eof;
IteratorSource(iterator_type& it, iterator_type end) : i(it), eof(end) {
}
std::streamsize read(char* s, std::streamsize n) {
for(int j = 0; j < n; j++) {
if(i == eof) {
std::cout << "Reached eof after " << j << " bytesn";
return -1;
}
char next = *i++;
std::cout << "Reading " << next << "n";
*s++ = next;
}
return n;
}
};
并像这样使用它:
int main() {
std::vector<char> data_back = {'x78', 'x9c', 'x73', 'x04', 'x00', 'x00', 'x42', 'x00', 'x42'};
auto start = data_back.begin();
IteratorSource<char, decltype(data_back)::iterator> data(start, data_back.end());
boost::iostreams::filtering_istreambuf def;
def.push(boost::iostreams::zlib_decompressor());
def.push(data);
boost::iostreams::copy(def, std::cout);
return 0;
}
要提供此输出,请执行以下操作:
Reading x
Reading �
Reading s
Reading
Reading
Reading
Reading B
Reading
Reading B
Reached eof after 9 bytes
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::iostreams::zlib_error> >'
what(): zlib error
Aborted (core dumped)
我不确定为什么会产生错误,因为从文件加载工作正常。
编辑 为了回答澄清的问题(在下面的评论中),这是我对您的原始样本所做的一个微不足道的改编,即我的盒子上的 JustWorks™:
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/zlib.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <iostream>
#include <sstream>
template <class cha_type, class iterator_type>
struct my_source {
typedef cha_type char_type;
typedef boost::iostreams::source_tag category;
iterator_type& it;
iterator_type end;
my_source(iterator_type& it, iterator_type end = {}) : it(it), end(end)
{ }
std::streamsize read(char* s, std::streamsize n) {
std::streamsize result = 0;
while ((it!=end) && n--) {
++result;
*s++ = *it++;
}
return result;
}
};
int main() {
std::string const rawdata {'x', '234', '313', 'H', '315', '311', '311', 'W', '(', '317', '/', '312', 'I', '341', ' 02', ' ', ' 36', 'r', ' 04', 'g' };
std::istringstream iss(rawdata, std::ios::binary);
auto start = std::istreambuf_iterator<char>(iss);
my_source<char, decltype(start)> data(start);
boost::iostreams::filtering_istreambuf def;
def.push(boost::iostreams::zlib_decompressor());
def.push(data);
boost::iostreams::copy(def, std::cout);
}
在科里鲁现场观看
旧答案:
我认为您可以使用任何流,例如字符串流:
std::istringstream iss("hello worldn");
filtering_streambuf<input> def;
def.push(zlib_compressor());
def.push(iss);
boost::iostreams::copy(def, std::cout);
或解压:
std::string const rawdata {'x', '234', '313', 'H', '315', '311', '311', 'W', '(', '317', '/', '312', 'I', '341', ' 02', ' ', ' 36', 'r', ' 04', 'g' };
std::istringstream iss(rawdata, std::ios::binary);
filtering_streambuf<input> def;
def.push(zlib_decompressor());
def.push(iss);
boost::iostreams::copy(def, std::cout);
这在这里就像一个魅力。(对不起,八进制逃脱:这就是bash给我的
printf "%qn" "$(echo hello world | zlib-flate -compress)"
而且我懒得保持这种状态)。
查看完整示例 在科里鲁直播
或者,Boost Iostreams 接受流缓冲区,因此您可以等效地
def.push(*iss.rdbuf());
相关文章:
- 为char数组调整zlib-zpipe
- 基于boost的程序的静态链接——zlib问题
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话
- 需要从 istream 和 ostream 派生 iostream
- std::带有自定义缓冲区的 iostream 不允许我写入
- 为什么 zlib 放气初始化调用一次不起作用?
- 新的放置取决于 iostream
- 包含在 <initializer_list> <iostream>?
- 为什么在包含iostream时可以使用printf()?
- 安装 zlib 库仍然丢失错误
- ZLib GZIP Returning Z_BUF_ERROR(-5)
- 仅在 zlib c++ 库中强制动态编码
- 如果 iostream 对象不可复制,为什么以下代码是合法的?
- 为什么我必须在包含后写 std::cin <iostream>?
- 如何将带有空字符的字节数组馈送到 std::iostream 中?
- 磁力计代码:C++ vs C - iosstream,矢量 - 错误iostream:没有这样的文件或目录
- zlib 膨胀在使用小缓冲区时会损坏
- 通过boost asio iostream下载大文件的最快方法是什么?
- 为什么 VScode 在 .h 文件中显示"'iostream' file not found"?
- 包含iostream导致不同的二进制文件