2009-05-15 8 views
1

Ich verwende eine leicht modifizierte Version von DotZlib, die Teil des contrib-Verzeichnisses mit dem zlib-Quellcode ist, um einen Echtzeit-Datenstrom aufzublasen.DotZlib - Code zur Fehlerbehandlung auffüllen 1 Z_STREAM_END

Anstelle der regulären InflateInit muss ich InflateInit2 verwenden - aber das ist der einzige Unterschied zu der bereitgestellten Bibliothek.

Netherlesse nach ein paar Lesevorgänge erhalte ich Fehlercode 1 von der zlib und es gelingt mir nicht, wiederherzustellen, wenn Bytes hinzugefügt werden.

Der ursprüngliche Code aus dem zlib contrib Verzeichnis ist:

public override void Add(byte[] data, int offset, int count) 
     { 
      if (data == null) throw new ArgumentNullException(); 
      if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException() 
; 
      if ((offset+count) > data.Length) throw new ArgumentException(); 

      int total = count; 
      int inputIndex = offset; 
      int err = 0; 

      while (err >= 0 && inputIndex < total) 
      { 
       copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); 
       err = inflate(ref _ztream, (int)FlushTypes.None); 
       if (err == 0) 
        while (_ztream.avail_out == 0) 
        { 
         OnDataAvailable(); 
         err = inflate(ref _ztream, (int)FlushTypes.None); 
        } 

       inputIndex += (int)_ztream.total_in; 
      } 
      setChecksum(_ztream.adler); 
     } 

BTW Wer weiß, wie verbesserten Code beitragen? Die Implementierung ist schön gestaltet, aber aus meiner Sicht unvollständig.

+1

FYI, gibt es ein 100% verwaltet ZlibStream in DotNetZip - http://dotnetzip.codeplex.com. – Cheeso

+0

Ja - aber ich muss die Kompressionsunterstützung zu einer Echtzeitanwendung hinzufügen - daher muss ich maximale Leistung haben. – weismat

Antwort

1

Ich denke, dass

  err = inflate(ref _ztream, (int)FlushTypes.None); 
      if (err == 0) 
       while (_ztream.avail_out == 0) 
       { 
        OnDataAvailable(); 
        err = inflate(ref _ztream, (int)FlushTypes.None); 
       } 

  while (_ztream.avail_in > 0) 
      { 
       err = inflate(ref _ztream, (int)FlushTypes.None); 
       if (err!=0) 
        break; 
       OnDataAvailable(); 
      } 

sein sollte Es gibt zwei Probleme, die ich mit der ersten Version des Codes zu sehen:

  1. wenn aufblasen() Daten erzeugt, aber erzeugt nicht genügend Daten, um avai_out 0 zu sein, Sie werden OnDataAvailable nicht aufrufen, obwohl Daten verfügbar sind.
  2. Sie könnten inflate() aufrufen, obwohl avail_in 0 ist, was ich mir leicht vorstellen könnte, dass es zu einem Stream-End-Fehler kommen könnte.

(NB:.. Ich vermute, dass Sie mich in einer professionellen Kapazität wissen Diese Antwort liegt in einer privaten Kapazität gegeben und ist nicht auf meine Arbeit für meinen Arbeitgeber bezogen)

+0

Ich denke, dass dies der Fall sein könnte. Ich werde es testen - es passt zu dem, was ich unter http://www.koders.com/csharp/fidB377599DB0D658DEA5BD81F67CA407C4FE12E93B.aspx?s=login gesehen habe. – weismat

+0

Dieser Fall wird ordnungsgemäß behandelt, aber wie kann ich einen Memory-Fehler richtig wiederherstellen - sollte ich den Puffer freigeben und zuweisen? Die Dokumentation zu inflateReset ist nicht so klar. – weismat

+0

Über welche Art von Speicherfehler sprechen wir? Aufblasen gibt Z_MEM_ERROR zurück? Oder etwas anderes? –