267
253
list_to_binary(Bs).
270
Bin0 = if list(Data) ->
271
list_to_binary(Data);
255
gzip(Data) when is_binary(Data); is_list(Data) ->
278
deflateInit(Z, default, deflated, -?MAX_WBITS, 8, default),
279
Bs = deflate(Z, Bin0, finish),
257
deflateInit(Z, default, deflated, 16+?MAX_WBITS, 8, default),
258
Bs = deflate(Z, Data, finish),
281
Crc = crc32(Z, Bin0),
283
%% add header and crc
284
Head = write_gzip_header(#gzip {}),
285
Tail = <<Crc:32/little, (size(Bin0)):32/little>>,
286
list_to_binary([Head,Bs,Tail]).
261
iolist_to_binary(Bs);
262
gzip(_) -> erlang:error(badarg).
288
gunzip(Bin0 = <<?ID1, ?ID2, Method, Flags, MTime:32,
289
XFlags, OsType, _/binary>>) ->
290
Gz0 = #gzip { method = Method,
295
{_,Bin1} = read_gzip_header(Flags, Bin0, 10, Gz0),
296
%% io:format("gunzip header = ~p\n", [Gz1]),
264
gunzip(Data) when is_binary(Data); is_list(Data) ->
298
inflateInit(Z, -?MAX_WBITS),
299
Bs = inflate(Z, Bin1),
301
Remain = getQSize(Z),
266
inflateInit(Z, 16+?MAX_WBITS),
267
Bs = inflate(Z, Data),
304
Offset = size(Bin1) - Remain,
305
Bin2 = list_to_binary(Bs),
306
<<_:Offset/binary, Crc32:32/little, Length:32/little, _/binary>> = Bin1,
308
erlang:error(bad_crc);
309
Length =/= size(Bin2) ->
310
erlang:error(bad_length);
315
erlang:error(badarg).
318
write_gzip_header(Gz) ->
320
if Gz#gzip.extra == undefined ->
323
Extra = list_to_binary([Gz#gzip.extra]),
324
{ <<(size(Extra)):16/little, Extra/binary>>, ?FEXTRA}
327
if Gz#gzip.name == undefined ->
330
Name = list_to_binary([Gz#gzip.name, 0]),
334
if Gz#gzip.comment == undefined ->
337
Comment = list_to_binary([Gz#gzip.comment, 0]),
338
{ Comment, ?FCOMMENT }
341
if Gz#gzip.crc == undefined ->
344
{ <<(Gz#gzip.crc):16/little >>, ?FHCRC }
348
(F1 bor F2 bor F3 bor F4):8,
349
(Gz#gzip.mtime):32/little,
352
D1/binary, D2/binary, D3/binary, D4/binary>>.
355
%% read the variable part of the gzip header
356
read_gzip_header(Flags, Binary, Offs0, Gz0) ->
358
if (Flags band ?FEXTRA) =/= 0 ->
359
<<_:Offs0/binary, Len:16/little, _/binary>> = Binary,
361
<<_:Offs00/binary, Extra:Len/binary,_/binary>> = Binary,
362
{Gz0#gzip{extra = Extra}, Offs0 + 2 + Len};
367
if (Flags band ?FNAME) =/= 0 ->
368
Name = cname(Binary, Offs1),
369
{Gz1#gzip{name = Name}, Offs1 + length(Name)+1};
374
if (Flags band ?FCOMMENT) =/= 0 ->
375
Comment = cname(Binary, Offs2),
376
{Gz2#gzip{comment = Comment}, Offs2 + length(Comment)+1};
381
if (Flags band ?FHCRC) =/= 0 ->
382
<<_:Offs3, Crc:16/little, _/binary>> = Binary,
383
{Gz3#gzip{crc = Crc}, Offs3+2};
387
<<_:Offs4/binary, Body/binary>> = Binary,
391
cname(Binary, Offs) ->
393
<<_:Offs/binary, C, _/binary>> ->
395
true -> [C|cname(Binary, Offs+1)]
270
iolist_to_binary(Bs);
271
gunzip(_) -> erlang:error(badarg).