2012-02-02 2 views
10

Я реализовал распаковку файлов gzip/zlib, как показано в их примерах на сайте boost.boost gzip decasp byte array

void CompressionUtils::Inflate(std::ifstream& inputFile, 
           std::ofstream& outputFile) 
{ 
    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::gzip_decompressor()); 
    in.push(inputFile); 
    boost::iostreams::copy(in, outputFile); 
} 

это работает нормально. Я также читаю данные из сокета, который я получаю от службы JSON, основанной на отдыхе, которая также сжата. Я решил, что буду писать реализацию на основе памяти, насколько это сложно. Ну, я понял, что я не понимаю потоки и потоковые буферы, как должен. Я обвиняю последние несколько лет в Java;) .. Поэтому я начал с этого пути.

void CompressionUtils::Inflate(char* compressed, 
           int size, 
           char* decompressed) 
{ 

    boost::iostreams::stream<boost::iostreams::array_source> source(compressed,size); 
    //std::stringstream str; 

    boost::iostreams::filtering_streambuf<boost::iostreams::input> in; 
    in.push(boost::iostreams::gzip_decompressor()); 
    in.push(source); 
    //boost::iostreams::copy(in, str); 
} 

Но я в растерянности относительно того, какого рода поток, я могу использовать, чтобы в основном получить распакованный char* представление распакованного потока. Это должно быть легко и возможно, но я трачу последние пару часов на неудачные попытки.

ответ

6

Очевидно, вы столкнулись с filtering streams and stream buffers. Вы можете использовать тот же метод в обратном порядке, чтобы получать данные в строку.

Я не мои собственные примеров удобно, поэтому считаю, что это несколько псевдо-код, но это должно быть то, что вы ищете:

namespace io = boost::iostreams; //<-- good practice 
typedef std::vector<char> buffer_t; 

void CompressionUtils::Inflate(const buffer_t &compressed, 
           buffer_t &decompressed) 
{ 
    io::filtering_ostream os; 

    os.push(io::gzip_decompressor()); 
    os.push(io::back_inserter(decompressed)); 

    io::write(os, &compressed[0], compressed.size()); 
} 

Таким образом, вы можете использовать задние вставки, представленные Увеличение.

В общем, то, что делает вышеприведенный код, определяет поток вывода, который вы можете записать. Он настроен таким образом, что все содержимое, записанное в него, сначала будет распаковано на gzip, а , затем, добавлено к back_inserter, которое, как и back_inserters, вставляет обратно в буфер decompressed.

Кроме того, как вы можете видеть, буферы завернуты в std::vector. Дайте мне знать, если это сработает для вас.

+0

Большое спасибо за ваш ответ. Я дам ему попробовать –