Der gzip-Container nach RFC 1952 — der Rahmen um DEFLATE, den std.zlib liefert. Erzeugte Dateien lassen sich mit gunzip auspacken, und von gzip erzeugte Dateien liest diese Unit.
Der Aufwand steckt nicht im Komprimieren, sondern in drei Kleinigkeiten des Formats:
FEXTRA (Länge + Daten), FNAME und FCOMMENT (nullterminiert) und FHCRC folgen. Wer sie nicht überspringt, setzt den DEFLATE-Strom an der falschen Stelle an — und merkt es erst, wenn der Trailer nicht passt.FHCRC obendrein, obwohl der RFC dort auch bloßes Überspringen erlaubt.cat a.gz b.gz). Sie werden nacheinander ausgepackt und aneinandergehängt — so verhält sich gzip -d auch.
Autor: Andreas Röne
Copyright: 2024-2026 Andreas Röne
→ std.zlib · std.brotli · std.zstd · Standard Library
| Signatur | Beschreibung |
|---|---|
GzipCompressBound(srcLen: int64): int64 | Obergrenze der Ausgabegröße — so viel muss der Zielpuffer fassen |
GzipCompress(src, srcLen, dst, dstMax): int64 | Packt als ein gzip-Member; liefert die geschriebenen Bytes oder GZIP_OVERFLOW |
GzipDecompress(src, srcLen, dst, dstMax): int64 | Packt aus; liefert die geschriebenen Bytes, GZIP_ERR oder GZIP_OVERFLOW |
| Konstante | Wert | Bedeutung |
|---|---|---|
GZIP_OK | 0 | Erfolg |
GZIP_ERR | -1 | Kein gzip, verstümmelt oder Prüfsumme falsch |
GZIP_OVERFLOW | -2 | Ausgabepuffer zu klein |
import std.io;
import std.gzip;
fn main(): int64 {
var src: pchar := "Hallo Welt Hallo Welt Hallo Welt"c;
var bound: int64 := GzipCompressBound(32);
var dst: int64 := alloc(bound);
var n: int64 := GzipCompress(src as int64, 32, dst, bound);
PrintLn(IntToStr(n)); // geschriebene Bytes
var back: int64 := alloc(256);
var m: int64 := GzipDecompress(dst, n, back, 256);
PrintLn(IntToStr(m)); // 32 — wieder die Ausgangslänge
return 0;
}
GzipCompress schreibt den schlanken Kopf ohne optionale Felder: kein Dateiname, kein Kommentar, kein Zeitstempel. Nach RFC 1952 §2.3.1.2 genügt einem konformen Kompressor, ID1, ID2, CM, CRC32 und ISIZE richtig zu setzen und die übrigen Felder auf Vorgabewerten zu lassen.
MTIME = 0 heißt im RFC ausdrücklich „kein Zeitstempel vorhanden„. Das ist eine bewusste Entscheidung: Ein echter Zeitstempel wäre eine verdeckte Abhängigkeit von der Uhr und machte die Ausgabe unreproduzierbar — dieselbe Eingabe ergäbe bei jedem Lauf eine andere Datei.
Beim Auspacken werden alle optionalen Felder dagegen gelesen bzw. übersprungen. Ein gesetztes reserviertes Flag-Bit führt zu GZIP_ERR: Es könnte ein neues Feld ankündigen, das alles Folgende verschiebt — dann wäre stilles Weiterdekodieren Raten.
Anders als std.brotli und std.zstd, die nur den Store-Modus schreiben, komprimiert GzipCompress wirklich — über DeflateCompressLZ77 aus std.zlib. 4096 Byte mit vierstelligem Muster ergeben 65 Byte Ausgabe; sehr kurze, unregelmäßige Eingaben können durch Kopf und Trailer (18 Byte) dennoch wachsen. FDICT gibt es in gzip nicht und ist entsprechend nicht vorgesehen.
dstMaxmuss mindestensGzipCompressBound(srcLen)sein — nicht bloß groß genug für das Ergebnis. Die Prüfung steht vor dem Komprimieren und vergleicht gegen die Obergrenze:
GzipCompress(src, 4096, dst, 256) // -> GZIP_OVERFLOW (-2), obwohl 65 Byte gereicht hätten
Den Zielpuffer also immer mitGzipCompressBoundbemessen (srcLen + srcLen/8 + 128) und nach dem Aufruf auf die zurückgegebene Länge zuschneiden.
Letzte Aktualisierung: 2026-08-11