2010-12-14 38 views
1

J'essaye de gonfler une chaîne en utilisant la déflateur de zlib, mais elle échoue, apparemment parce qu'elle n'a pas le bon en-tête. J'ai lu ailleurs que la solution C# à ce problème est:C++ zlib inflate failing - traduction de C# fixup?

public static byte[] FlateDecode(byte[] inp, bool strict) { 
    MemoryStream stream = new MemoryStream(inp); 
    InflaterInputStream zip = new InflaterInputStream(stream); 
    MemoryStream outp = new MemoryStream(); 
    byte[] b = new byte[strict ? 4092 : 1]; 
    try { 
     int n; 
     while ((n = zip.Read(b, 0, b.Length)) > 0) { 
      outp.Write(b, 0, n); 
     } 
     zip.Close(); 
     outp.Close(); 
     return outp.ToArray(); 
    } 
    catch { 
     if (strict) 
      return null; 
     return outp.ToArray(); 
    } 
} 

Mais je ne sais rien sur C#. Je peux supposer que tout ce qu'il fait est d'ajouter un préfixe à la chaîne, mais quel est ce préfixe, je n'en ai aucune idée. Quelqu'un pourrait-il exprimer cette fonction (ou même simplement la création de l'en-tête et la concaténation de chaînes) en C++?

Les données que j'essaie de gonfler sont extraites d'un fichier PDF en utilisant la déflation zlib.

Merci un million, Wyatt

+0

vous pouvez formater votre code en le sélectionnant et en appuyant sur l'icône '101010'. Je l'ai fait cette fois. –

+0

Désolé, juste un oubli. Apprends-moi à travailler à quatre heures du matin. – wyatt

+0

Tout d'abord, essayez de dégonfler certaines données aléatoires avec zlib. Si votre code peut le gonfler, le problème est avec les données que vous avez. Sinon, postez votre code C++ afin que nous puissions rechercher ensemble les erreurs possibles. –

Répondre

1

J'ai eu plus de chance en utilisant SharpZipLib pour zlib Interop qu'avec les classes natives .Net Framework. Cela gère correctement les flux à partir de C++ (natif zlib) et des classes de compression de Java sans qu'aucune entreprise drôle ne soit nécessaire.

+0

Merci pour cela, et je le garderai à l'esprit pour l'avenir. Malheureusement, je n'utilise pas actuellement .NET. Connaissez-vous une solution alternative qui fonctionnera avec MINGW? – wyatt

+0

@wyatt - Je vois que ma réponse a manqué votre point. Pourquoi ne publiez-vous pas votre code C++ qui échoue et le prenez à partir de là?Vous pouvez modifier le code C++ dans la question. zlib en C++ devrait être un slam dunk, selon l'origine du flux (quelle information devrait également être incluse dans la question). –

+1

Si vous n'utilisez pas .NET, quel est le but de cette question? Si votre question est du code C++, il peut être utile de ne pas poster de code C# et de poser une question .NET. –

0

Je ne vois aucun préfixe, désolé. Voici ce que la logique semble être; Désolé, ce n'est pas en C++:

MemoryStream stream = new MemoryStream(inp); 
InflaterInputStream zip = new InflaterInputStream(stream); 

Créer un flux décompressé à partir des données transmises

MemoryStream outp = new MemoryStream(); 

Créer un flux de mémoire tampon pour la sortie

byte[] b = new byte[strict ? 4092 : 1]; 
try { 
    int n; 
    while ((n = zip.Read(b, 0, b.Length)) > 0) { 

Si vous êtes dans le strict mode, read up to 4092 bytes - ou 1 en mode non strict - dans un tampon d'octets

 outp.Write(b, 0, n); 

écrire tous les octets décodés (peut être inférieure à la 4092) au courant de la mémoire tampon de sortie

zip.Close(); 
    outp.Close(); 
    return outp.ToArray(); 

nettoyer, et le retour du courant de mémoire tampon de sortie en tant que matrice.

Je suis un peu confus, cependant: pourquoi ne pas simplement couper le tableau b off à n éléments et le retourner plutôt que de passer par un MemoryStream? Le code doit également prendre soin de nettoyer les flux de mémoire et zip sur exception (par exemple en utilisant using) car ils sont tous IDisposable mais je suppose que ce n'est pas vraiment important car ils ne correspondent pas aux poignées de fichiers d'E/S, seulement structures de mémoire.