提升IOSTREAMS zlib_error与自定义源 [英] Boost Iostreams zlib_error with Custom Source
问题描述
我试图通过使用 zlib_decom pressor
来DECOM preSS数据的 istreambuf_iterator
。内置的方式来使用输入迭代器作为输入到流我无法找到一个(请指出的路要走,如果已经存在),所以我写了这篇来源:
I am trying to use a zlib_decompressor
to decompress data through an istreambuf_iterator
. I couldn't find an in built way to use an input iterator as input to a stream (please point out a way if one exists already) so I wrote this source:
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 << " bytes\n";
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)
我不知道为什么,因为从文件加载工作正常,这是产生一个错误。
I am not sure why this is producing an error because loading from a file works fine.
推荐答案
修改在回应澄清的问题(在下面的评论),这里是我做你的原始样品的一个微不足道的适应,这的 JustWorks™的在我的盒子:
EDIT In response to the clarified question (in the comments below), here's a trivial adaptation I did of your original sample, that JustWorks™ on my box:
#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', '\002', '\0', '\036', 'r', '\004', '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);
}
看它的 住在Coliru
See it Live On Coliru
我觉得你可以只使用任何流,如stringstream的:
I think you can use just any stream, like stringstream:
std::istringstream iss("hello world\n");
filtering_streambuf<input> def;
def.push(zlib_compressor());
def.push(iss);
boost::iostreams::copy(def, std::cout);
或DECOM preSS:
or to decompress:
std::string const rawdata {'x', '\234', '\313', 'H', '\315', '\311', '\311', 'W', '(', '\317', '/', '\312', 'I', '\341', '\002', '\0', '\036', 'r', '\004', '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);
这就像这里的魅力。 (对不起,八进制转义:这是什么庆典给了我
This works like a charm here. (Sorry for the octal escapes: it's what bash gave me
printf "%q\n" "$(echo hello world | zlib-flate -compress)"
和我够懒,以保持这种方式)。
and I'm lazy enough to keep it that way).
请参阅完整的例子 住在Coliru
See full example Live on Coliru
或者升压IOSTREAMS接受streambuffer,这样你就可以等效
Alternatively Boost Iostreams accepts a streambuffer, so you can equivalently
def.push(*iss.rdbuf());
这篇关于提升IOSTREAMS zlib_error与自定义源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!