/** * Simple Gzip compression/decompression. * * 2007 Vladimir Panteleev */ module Gzip; static import zlib = std.zlib; static import stdcrc32 = crc32; debug import std.stdio, std.file; private enum { FTEXT = 1, FHCRC = 2, FEXTRA = 4, FNAME = 8, FCOMMENT = 16 } uint crc32(void[] data) { uint crc = stdcrc32.init_crc32(); foreach(v;cast(ubyte[])data) crc = stdcrc32.update_crc32(v, crc); return ~crc; } void[] compress(void[] data) { ubyte[] header; header.length = 10; header[0] = 0x1F; header[1] = 0x8B; header[2] = 0x08; header[3..8] = 0; // TODO: set MTIME header[8] = 4; header[9] = 3; // TODO: set OS uint[2] footer = [crc32(data), data.length]; ubyte[] compressed = cast(ubyte[])zlib.compress(data, 9); return header ~ compressed[2..$-4] ~ cast(ubyte[])footer; } void[] uncompress(void[] data) { assert(data.length>=10); ubyte[] header = cast(ubyte[])data[0..10]; assert(header[0] == 0x1F); assert(header[1] == 0x8B); assert(header[2] == 0x08); assert(header[3] == 0); // TODO: support (skipping of) extra fields void[] uncompressed = zlib.uncompress(data[header.length..$-8], 0, -15); assert(uncompressed.length == *cast(uint*)(&data[$-4])); return uncompressed; }