2010-03-18 3 views
3

Y at-il un peu de magie nécessaire pour obtenir un "zlib sync flush" lors de l'utilisation boost::iostreams::zlib_compressor? Il suffit d'appeler flush sur le filtre, ou strict_sync sur un filtering_ostream le contenant ne voit pas le travail (ie je veux que le compresseur vole suffisamment pour que le décompresseur puisse récupérer tous les octets consommés par le compresseur jusqu'à présent, sans fermer le flux).Vider un boost :: iostreams :: zlib_compressor. Comment obtenir une "synchro flush"?

En regardant le header, il semble y avoir quelques « codes flush » définis (notamment un sync_flush), mais on ne sait pas bien comment ils devraient être utilisés (en gardant à l'esprit mon compresseur vient d'être ajouté dans un filtering_ostream).

Répondre

1

Il se trouve qu'il ya un problème fondamental que les symmetric_filter que zlib_compressor hérite de lui-même est pas flushable (ce qui semble plutôt un oubli).

Ajouter éventuellement un tel support à symmetric_filter serait aussi simple que d'ajouter le flushable_tag et d'exposer les méthodes de vidage privées existantes, mais pour l'instant je peux vivre avec.

0

Ce C++ bibliothèque wrapper zlib, dont je suis l'auteur, prend en charge la fonctionnalité de rinçage et est sans doute plus simple à utiliser:

https://github.com/rudi-cilibrasi/zlibcomplete

Il est aussi facile que cela:

#include <iostream> 
#include <zlc/zlibcomplete.hpp> 

using namespace zlibcomplete; 
using namespace std; 

int main(int argc, char **argv) 
{ 
    const int CHUNK = 16384; 
    char inbuf[CHUNK]; 
    int readBytes; 
    ZLibCompressor compressor(9, auto_flush); 
    for (;;) { 
    cin.read(inbuf, CHUNK); 
    readBytes = cin.gcount(); 
    if (readBytes == 0) { 
     break; 
    } 
    string input(inbuf, readBytes); 
    cout << compressor.compress(input); 
    } 
    cout << compressor.finish(); 
    return 0; 
} 

La principale différence avec boost est qu'au lieu d'utiliser un filtre de classe template, il suffit de passer une chaîne et d'écrire la chaîne compressée qui en résulte autant de fois que vous le souhaitez. Chaque chaîne sera vidée (en mode auto_flush) afin de pouvoir être utilisée dans les protocoles réseau interactifs. A la fin, appelez finish pour obtenir le dernier bit de données compressées et un bloc de terminaison. Tandis que l'exemple de boost est plus court, il nécessite d'utiliser deux autres classes de template moins connues: std :: string, à savoir filteringstreambuf et boost: iostreams: copy. L'interface boost de zlib est incomplète car elle ne supporte pas Z_SYNC_FLUSH. Cela signifie qu'il n'est pas approprié pour les applications de streaming en ligne telles que les protocoles interactifs TCP. J'aime booster et l'utiliser comme ma bibliothèque de support C++ principale dans tous mes projets C++ mais dans ce cas particulier elle n'était pas utilisable dans mon application en raison de la fonctionnalité de vidage manquante.

+0

Peut-être que vous pouvez démontrer un exemple concret ici sur StackOverflow sur _how_ à votre avis, en tant qu'auteur de la bibliothèque, est simpeler à utiliser? –

+0

Merci, je l'ai fait, apprécie les commentaires. –

Questions connexes