Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi ZLib - String komprimieren dekomprimieren (https://www.delphipraxis.net/167032-zlib-string-komprimieren-dekomprimieren.html)

himitsu 9. Mär 2012 22:20

ZLib - String komprimieren dekomprimieren
 
Zitat:

Zitat von roboter202
Hallo,

ich hab grad deinen Thread über ZLib und das komprimieren von Strings gelesen => hier.

Leider hat es bei mir nicht auf anhieb geklappt. Kann es sein das es statt
Delphi-Quellcode:
CompressBuf(Input[1],[...]
,
Delphi-Quellcode:
CompressBuf(@Input[1],[...]
heißen muss, denn es wird ja ein Pointer kein Char erwartet?

Naja ich wollte das nur anmerken nicht das noch einer dran verzweifelt ;-)
Kann ja mal passieren.

Ich möchte diesbezüglich noch etwas zum Eintrag hinzufügen:

Es wurde die/eine CompressBuf-Funktion verwendet, welche untypisierte Var- und Const-Parameter verwedete.
Ist nur ein CompressBuf mit Pointern vorhanden, dann fehlen dort natürlich noch die @.

Außerdem ist diese Funktion ist nur auf den AnsiString zugeschnitten, also nur bis Delphi 2006 / Turbo Delphi ordentlich funktionsfähig.

Delphi-Quellcode:
Uses ZLib;

Function CompressAnsiString(const Input: AnsiString): RawByteString;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      CompressBuf(Input[1], Length(Input), Buffer, BufSize);
      SetLength(Result, BufSize);
      Move(Buffer^, Result[1], BufSize);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;

Function DeCompressAnsiString(const Input: RawByteString): AnsiString;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      DeCompressBuf(Input[1], Length(Input), 0, Buffer, BufSize);
      SetLength(Result, BufSize);
      Move(Buffer^, Result[1], BufSize);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;

Function CompressWideString(const Input: UnicodeString): RawByteString; overload;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      CompressBuf(Input[1], Length(Input) * 2, Buffer, BufSize);
      SetLength(Result, BufSize);
      Move(Buffer^, Result[1], BufSize);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;

Function DeCompressWideString(const Input: RawByteString): UnicodeString;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      DeCompressBuf(Input[1], Length(Input), 0, Buffer, BufSize);
      SetLength(Result, BufSize div 2);
      Move(Buffer^, Result[1], BufSize div 2);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;

Function CompressString(const Input: String): RawByteString;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      CompressBuf(Input[1], Length(Input) * SizeOf(Char), Buffer, BufSize);
      SetLength(Result, BufSize);
      Move(Buffer^, Result[1], BufSize);
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;

Function DeCompressString(const Input: RawByteString): String;
  Var Buffer: Pointer;
    BufSize: Integer;

  Begin
    Buffer := nil;
    Try
      DeCompressBuf(Input[1], Length(Input), 0, Buffer, BufSize);
      SetLength(Result, BufSize div SizeOf(Char));
      Move(Buffer^, Result[1], BufSize div SizeOf(Char));
    Finally
      If Buffer <> nil Then FreeMem(Buffer);
    End;
  End;
Statt dem RawByteString könnte man auch einen AnsiString oder TBytes (Array of Byte) verwenden.
(beim Array nicht vergessen, daß dort der Startindex [0] und nicht [1] ist)


Und bei aktuelleren den ZLib-Versionen kann man nun auch direkt auf vorhandene Funktionen zurückgreifen.
Delphi-Quellcode:
function ZCompressStr(const s: string; level: TZCompressionLevel = zcDefault): TBytes;
function ZCompressStr(const s: string; level: TCompressionLevel): TBytes; // CG: Add overload to take old enum type
function ZDecompressStr(const s: TBytes): string;
[edit]
Ich merk grade was ... die von SubData erwähnte Version ... Ich denke mal, daß ist die selbe, welche nun im Delphi direkt verbaut ist. (seit mindestend Delphi 2010)
Wem dort nun die Version für UTF8String oder AnsiString fehlt, der nehme einfach
Delphi-Quellcode:
function ZCompressStr(const s: RawByteString; level: TZCompressionLevel): TBytes;
var
  buffer: Pointer;
  size: Integer;
begin
  ZCompress(PAnsiChar(s), Length(s), buffer, size, level);
  try
    SetLength(Result, size);
    Move(buffer^, pointer(result)^, size);
  finally
    FreeMem(buffer);
  end;
end;
(nur etwas unschön, daß dort immernoch die Resourcenschutzblöcke vergessen wurden :shock: )


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz