Распакуйте файл из Boost filtering_streambuf в std :: vector & lt; char & gt ;?

Я пытаюсь распаковать файл, который был сжат с использованием алгоритма DEFLATE, и вставить его в vector<unsigned char>, Из исследований, которые я провел до сих пор, казалось, что я мог бы использовать boost::iostreams::filtering_streambuf а затем использовать boost::iostreams::copy() чтобы получить это в boost::interprocess::basic_vectorstream<std::vector<unsigned char>> и затем вытяните нижележащий вектор из векторного потока. Тем не менее, я получаю кучу ошибок компилятора, начиная с этого:

/usr/include/boost/iostreams/copy.hpp: In function ‘std::streamsize boost::iostreams::detail::copy_impl(Source, Sink, std::streamsize) [with Source = boost::reference_wrapper<boost::iostreams::filtering_streambuf<boost::iostreams::input> >, Sink = boost::reference_wrapper<boost::interprocess::basic_vectorstream<std::vector<unsigned char> > >, std::streamsize = long int]’:
/usr/include/boost/iostreams/copy.hpp:245:79:   instantiated from ‘std::streamsize boost::iostreams::copy(Source&, Sink&, std::streamsize, typename boost::enable_if<boost::iostreams::is_std_io<Source> >::type*, typename boost::enable_if<boost::iostreams::is_std_io<Sink> >::type*) [with Source = boost::iostreams::filtering_streambuf<boost::iostreams::input>, Sink = boost::interprocess::basic_vectorstream<std::vector<unsigned char> >, std::streamsize = long int, typename boost::enable_if<boost::iostreams::is_std_io<Source> >::type = void, typename boost::enable_if<boost::iostreams::is_std_io<Sink> >::type = void]’
ValueFileReader.cpp:92:41:   instantiated from here
/usr/include/boost/iostreams/copy.hpp:178:5: error: static assertion failed: "(is_same<src_char, snk_char>::value)"

Код, который я использую, приведен ниже (здесь для краткости сокращен и выполняется «использование пространства имен»):

using namespace boost::iostreams;
using namespace boost::interprocess;

filtering_streambuf<input> in;
std::ifstream file(filename, std::ifstream::in);
in.push(zlib_decompressor());
in.push(file);

basic_vectorstream<std::vector<unsigned char>> vectorStream;
copy(in, vectorStream);
std::vector<unsigned char> chars(vectorStream.vector());

я видел эта тема, но я не был уверен, что если скопировать все в вектор, то распаковка из вектора будет наиболее эффективным способом решения этой проблемы.

Есть ли лучший способ, которым я могу пойти по этому поводу, или у меня есть правильная идея, но какая-то ошибка в коде?

1

Решение

Проблема в том, что ваш ifstream а также filtering_streambuf использование char в качестве основного типа символов, но ваш basic_vectorstream использования unsigned char как его тип значения. В коде Boost есть статическое утверждение, требующее, чтобы эти типы были одинаковыми, чтобы не возникало множество ошибок компиляции, если вы используете два разных типа, которые не конвертируемы.

К счастью, исправить это легко — изменить:

basic_vectorstream<std::vector<unsigned char>> vectorStream;
copy(in, vectorStream);
std::vector<unsigned char> chars(vectorStream.vector());

чтобы:

basic_vectorstream<std::vector<char>> vectorStream;
copy(in, vectorStream);
std::vector<unsigned char> chars(
vectorStream.vector().begin(),
vectorStream.vector().end()
);

Это безопасно, потому что char а также unsigned char гарантируется стандартом C ++ иметь одинаковое представление объекта (§3.9.1 / 1).


Не имеет отношения к вашей прямой проблеме, но вы также должны пройти std::ios::binary в fileконструктор, в противном случае вы будете иметь поврежденные данные из-за конвертации в конце строки.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]