Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - ZLib EDecompressionError bei DecompressToUserBuf


derDoc - Mo 01.03.10 23:19
Titel: ZLib EDecompressionError bei DecompressToUserBuf
Ich habe hier ein kleines Problem mit einem Fehler beim Versuch einen Buffer zu dekomprimieren. Ich verwende dazu die Delphi beiliegende ZLib.pas.

Beim Ausführen von folgendem Code bekomme ich einen EDecompressionError mit der vielsagenden Aussage 'Error'.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Buffer, DecBuffer: array of Byte;
...
SetLength(Buffer, {Komprimierte Größe in Byte});
SetLength(DecBuffer, {Unkomprimierte Größe in Byte});
... //Zwischenzeitlich wird Buffer vollständig mit Daten gefüllt
DecompressToUserBuf(@Buffer[0], Length(Buffer), @DecBuffer[0], Length(DecBuffer));


Ein weiteres Problem liegt darin, dass dieser Fehler nur bei manchen Buffern auftritt. Ich kann einige ohne Probleme dekomprimieren, während ich bei anderen eben diesen Fehler habe. Die einzigen drei Veränderungen dabei sind jeweils die Daten im Buffer, die komprimierte Menge an Daten und die unkomprimierte Menge Daten.

Edit:
Mir ist aufgefallen, dass in den Fällen, in denen dieser Fehler auftritt, die Anzahl der dekomprimierten Bytes von der mir bekannten Anzahl abweicht. Beispiel: komprimierte Größe 73 Bytes, unkomprimierte Größe 540 Bytes, von DecompressBuf ausgegebene Bytes 593.


Astat - Di 02.03.10 16:24

Hallo derDoc, anbei mal Streaming Sample als Vorlage.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
function CompressStream(inStream, outStream : TMemoryStream) : integer;
var
  Count, outCount : integer;
  outPtr : pointer;
begin
  Count := inStream.Size;
  Result := Count;
  CompressBuf(inStream.Memory, Count, outPtr, outCount);
  outStream.Write(outPtr^, outCount);
end;

procedure DecompressStream(inStream, outStream: TMemoryStream; FileSz : integer);
var
  Count : integer;
  outPtr : pointer;
begin
  Count := inStream.Size;
  FileSz := FileSz + 2048;
  GetMem(outPtr,FileSz);
  DecompressToUserBuf(inStream.Memory, Count, outPtr, FileSz);
  outStream.Write(outPtr^,FileSz);
  FreeMem(outPtr,FileSz);
end;


lg. Astat