2012-02-02 11 views
10

Ho implementato la decompressione gzip/zlib dei file come mostrato nei loro esempi sul sito boost.boost gzip decompress array di byte

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); 
} 

funziona correttamente. Sto anche leggendo i dati da un socket che sto ricevendo da un servizio JSON basato sul resto che è compresso pure. Ho pensato che avrei scritto un'implementazione basata sulla memoria, quanto potesse essere difficile. Bene, ho capito che non capisco i flussi e gli stream buffer come dovrei. Incolpo degli ultimi anni in Java;) .. Così ho iniziato questo percorso.

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); 
} 

ma io sono ad una perdita quanto a che tipo di flusso che posso usare per ottenere fondamentalmente la decompresso char* rappresentazione del flusso decompresso. Questo dovrebbe essere facile, e probabilmente lo è, ma ho sprecato le ultime due ore a trovare tentativi falliti.

risposta

6

Ovviamente, hai trovato filtering streams and stream buffers. È possibile utilizzare lo stesso metodo al contrario per ottenere dati in una stringa.

Non ho i miei esempi a portata di mano, in modo da considerare questo per essere un po 'pseudo-codice, ma questo dovrebbe essere quello che stai cercando:

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()); 
} 

modo da poter utilizzare l'inseritore posteriore fornito da Incremento.

Fondamentalmente, ciò che il codice precedente fa è definire un flusso di output su cui è possibile scrivere. È impostato in modo tale che tutto il contenuto scritto su di esso venga prima decompresso per gzip e quindi aggiunto allo back_inserter che, come back_inserter, inserirà nel retro del buffer decompressed.

Inoltre, come si può vedere, i buffer sono avvolti in std::vector. Fammi sapere se questo funziona per te.

+0

Grazie mille per la risposta. Farò un tentativo –