1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 2003-2018. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20 21-module(zlib). 22 23-export([open/0,close/1,set_controlling_process/2, 24 deflateInit/1,deflateInit/2,deflateInit/6, 25 deflateSetDictionary/2,deflateReset/1,deflateParams/3, 26 deflate/2,deflate/3,deflateEnd/1, 27 inflateInit/1,inflateInit/2,inflateInit/3, 28 inflateSetDictionary/2,inflateGetDictionary/1, inflateReset/1, 29 inflate/2,inflate/3,inflateEnd/1, 30 inflateChunk/2,inflateChunk/1, 31 safeInflate/2, 32 setBufSize/2,getBufSize/1, 33 crc32/1,crc32/2,crc32/3,adler32/2,adler32/3, 34 crc32_combine/4,adler32_combine/4, 35 compress/1,uncompress/1,zip/1,unzip/1, 36 gzip/1,gunzip/1]). 37 38-export([on_load/0]). 39 40%% These are soft-deprecated until OTP 21. 41% -deprecated([inflateChunk/1, inflateChunk/2, 42% getBufSize/1, setBufSize/2, 43% crc32/1,crc32/2,crc32/3,adler32/2,adler32/3, 44% crc32_combine/4,adler32_combine/4]). 45 46-export_type([zstream/0, zflush/0, zlevel/0, zwindowbits/0, zmemlevel/0, 47 zstrategy/0]). 48 49%% flush argument encoding 50-define(Z_NO_FLUSH, 0). 51-define(Z_SYNC_FLUSH, 2). 52-define(Z_FULL_FLUSH, 3). 53-define(Z_FINISH, 4). 54 55%% compression level 56-define(Z_NO_COMPRESSION, 0). 57-define(Z_BEST_SPEED, 1). 58-define(Z_BEST_COMPRESSION, 9). 59-define(Z_DEFAULT_COMPRESSION, (-1)). 60 61%% compresssion strategy 62-define(Z_FILTERED, 1). 63-define(Z_HUFFMAN_ONLY, 2). 64-define(Z_RLE, 3). 65-define(Z_DEFAULT_STRATEGY, 0). 66 67%% deflate compression method 68-define(Z_DEFLATED, 8). 69 70-define(MAX_WBITS, 15). 71 72-define(DEFAULT_MEMLEVEL, 8). 73-define(DEFAULT_WBITS, 15). 74 75-define(EOS_BEHAVIOR_ERROR, 0). 76-define(EOS_BEHAVIOR_RESET, 1). 77-define(EOS_BEHAVIOR_CUT, 2). 78 79%% Chunk sizes are hardcoded on account of them screwing with the 80%% predictability of the system. zlib is incapable of trapping so we need to 81%% ensure that it never operates on any significant amount of data. 82-define(DEFLATE_IN_CHUNKSIZE, 8 bsl 10). 83-define(DEFLATE_OUT_CHUNKSIZE, 8 bsl 10). 84-define(INFLATE_IN_CHUNKSIZE, 8 bsl 10). 85-define(INFLATE_OUT_CHUNKSIZE, 16 bsl 10). 86 87%%------------------------------------------------------------------------ 88 89%% Public data types. 90-type zstream() :: reference(). 91-type zflush() :: 'none' | 'sync' | 'full' | 'finish'. 92 93-type zlevel() :: 94 'none' | 'default' | 'best_compression' | 'best_speed' | 0..9. 95-type zstrategy() :: 'default' | 'filtered' | 'huffman_only' | 'rle'. 96 97-type zmemlevel() :: 1..9. 98-type zwindowbits() :: -15..-8 | 8..47. 99 100%% Private data types. 101 102-type zmethod() :: 'deflated'. 103 104-record(zlib_opts, { 105 stream :: zstream() | 'undefined', 106 method :: function(), 107 input_chunk_size :: pos_integer(), 108 output_chunk_size :: pos_integer(), 109 flush :: non_neg_integer() 110 }). 111 112%%------------------------------------------------------------------------ 113 114on_load() -> 115 case erlang:load_nif(atom_to_list(?MODULE), 0) of 116 ok -> ok 117 end. 118 119-spec open() -> zstream(). 120open() -> 121 open_nif(). 122open_nif() -> 123 erlang:nif_error(undef). 124 125-spec close(Z) -> 'ok' when 126 Z :: zstream(). 127close(Z) -> 128 close_nif(Z). 129close_nif(_Z) -> 130 erlang:nif_error(undef). 131 132-spec set_controlling_process(Z, Pid) -> 'ok' when 133 Z :: zstream(), 134 Pid :: pid(). 135set_controlling_process(Z, Pid) -> 136 set_controller_nif(Z, Pid). 137set_controller_nif(_Z, _Pid) -> 138 erlang:nif_error(undef). 139 140-spec deflateInit(Z) -> 'ok' when 141 Z :: zstream(). 142deflateInit(Z) -> 143 deflateInit(Z, default). 144 145-spec deflateInit(Z, Level) -> 'ok' when 146 Z :: zstream(), 147 Level :: zlevel(). 148deflateInit(Z, Level) -> 149 deflateInit(Z, Level, deflated, ?DEFAULT_WBITS, ?DEFAULT_MEMLEVEL, default). 150 151-spec deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> 'ok' when 152 Z :: zstream(), 153 Level :: zlevel(), 154 Method :: zmethod(), 155 WindowBits :: zwindowbits(), 156 MemLevel :: zmemlevel(), 157 Strategy :: zstrategy(). 158deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> 159 deflateInit_nif(Z, 160 arg_level(Level), 161 arg_method(Method), 162 arg_bitsz(WindowBits), 163 arg_mem(MemLevel), 164 arg_strategy(Strategy)). 165deflateInit_nif(_Z, _Level, _Method, _WindowBits, _MemLevel, _Strategy) -> 166 erlang:nif_error(undef). 167 168-spec deflateSetDictionary(Z, Dictionary) -> Adler32 when 169 Z :: zstream(), 170 Dictionary :: iodata(), 171 Adler32 :: non_neg_integer(). 172deflateSetDictionary(Z, Dictionary) -> 173 deflateSetDictionary_nif(Z, Dictionary). 174deflateSetDictionary_nif(_Z, _Dictionary) -> 175 erlang:nif_error(undef). 176 177-spec deflateReset(Z) -> 'ok' when 178 Z :: zstream(). 179deflateReset(Z) -> 180 deflateReset_nif(Z). 181deflateReset_nif(_Z) -> 182 erlang:nif_error(undef). 183 184-spec deflateParams(Z, Level, Strategy) -> ok when 185 Z :: zstream(), 186 Level :: zlevel(), 187 Strategy :: zstrategy(). 188deflateParams(Z, Level0, Strategy0) -> 189 Level = arg_level(Level0), 190 Strategy = arg_strategy(Strategy0), 191 Progress = deflate(Z, <<>>, sync), 192 case deflateParams_nif(Z, Level, Strategy) of 193 ok -> 194 save_progress(Z, deflate, Progress), 195 ok; 196 Other -> 197 Other 198 end. 199deflateParams_nif(_Z, _Level, _Strategy) -> 200 erlang:nif_error(undef). 201 202-spec deflate(Z, Data) -> Compressed when 203 Z :: zstream(), 204 Data :: iodata(), 205 Compressed :: iolist(). 206deflate(Z, Data) -> 207 deflate(Z, Data, none). 208 209-spec deflate(Z, Data, Flush) -> Compressed when 210 Z :: zstream(), 211 Data :: iodata(), 212 Flush :: zflush(), 213 Compressed :: iolist(). 214deflate(Z, Data, Flush) -> 215 Progress = restore_progress(Z, deflate), 216 enqueue_input(Z, Data), 217 append_iolist(Progress, dequeue_all_chunks(Z, deflate_opts(Flush))). 218 219deflate_opts(Flush) -> 220 #zlib_opts{ 221 method = fun deflate_nif/4, 222 input_chunk_size = ?DEFLATE_IN_CHUNKSIZE, 223 output_chunk_size = ?DEFLATE_OUT_CHUNKSIZE, 224 flush = arg_flush(Flush) 225 }. 226 227deflate_nif(_Z, _InputChSize, _OutputChSize, _Flush) -> 228 erlang:nif_error(undef). 229 230-spec deflateEnd(Z) -> 'ok' when 231 Z :: zstream(). 232deflateEnd(Z) -> 233 deflateEnd_nif(Z). 234deflateEnd_nif(_Z) -> 235 erlang:nif_error(undef). 236 237-spec inflateInit(Z) -> 'ok' when 238 Z :: zstream(). 239inflateInit(Z) -> 240 inflateInit(Z, ?DEFAULT_WBITS). 241 242-spec inflateInit(Z, WindowBits) -> 'ok' when 243 Z :: zstream(), 244 WindowBits :: zwindowbits(). 245inflateInit(Z, WindowBits) -> 246 inflateInit(Z, WindowBits, cut). 247 248-spec inflateInit(Z, WindowBits, EoSBehavior) -> 'ok' when 249 Z :: zstream(), 250 WindowBits :: zwindowbits(), 251 EoSBehavior :: error | reset | cut. 252inflateInit(Z, WindowBits, EoSBehavior) -> 253 inflateInit_nif(Z, arg_bitsz(WindowBits), arg_eos_behavior(EoSBehavior)). 254inflateInit_nif(_Z, _WindowBits, _EoSBehavior) -> 255 erlang:nif_error(undef). 256 257-spec inflateSetDictionary(Z, Dictionary) -> 'ok' when 258 Z :: zstream(), 259 Dictionary :: iodata(). 260inflateSetDictionary(Z, Dictionary) -> 261 inflateSetDictionary_nif(Z, Dictionary). 262inflateSetDictionary_nif(_Z, _Dictionary) -> 263 erlang:nif_error(undef). 264 265-spec inflateGetDictionary(Z) -> Dictionary when 266 Z :: zstream(), 267 Dictionary :: binary(). 268inflateGetDictionary(Z) -> 269 case inflateGetDictionary_nif(Z) of 270 Dictionary when is_binary(Dictionary) -> 271 Dictionary; 272 not_supported -> 273 erlang:error(enotsup) 274 end. 275inflateGetDictionary_nif(_Z) -> 276 erlang:nif_error(undef). 277 278-spec inflateReset(Z) -> 'ok' when 279 Z :: zstream(). 280inflateReset(Z) -> 281 inflateReset_nif(Z). 282inflateReset_nif(_Z) -> 283 erlang:nif_error(undef). 284 285-spec inflate(Z, Data) -> Decompressed when 286 Z :: zstream(), 287 Data :: iodata(), 288 Decompressed :: iolist(). 289inflate(Z, Data) -> 290 inflate(Z, Data, []). 291 292-spec inflate(Z, Data, Options) -> Decompressed when 293 Z :: zstream(), 294 Data :: iodata(), 295 Options :: list({exception_on_need_dict, boolean()}), 296 Decompressed :: iolist() | 297 {need_dictionary, 298 Adler32 :: non_neg_integer(), 299 Output :: iolist()}. 300inflate(Z, Data, Options) -> 301 enqueue_input(Z, Data), 302 Result = dequeue_all_chunks(Z, inflate_opts()), 303 case proplist_get_value(Options, exception_on_need_dict, true) of 304 true -> exception_on_need_dict(Z, Result); 305 false -> Result 306 end. 307 308inflate_nif(_Z, _InputChSize, _OutputChSize, _Flush) -> 309 erlang:nif_error(undef). 310 311inflate_opts() -> 312 #zlib_opts{ 313 method = fun inflate_nif/4, 314 input_chunk_size = ?INFLATE_IN_CHUNKSIZE, 315 output_chunk_size = ?INFLATE_OUT_CHUNKSIZE, 316 flush = arg_flush(none) 317 }. 318 319-spec inflateChunk(Z, Data) -> Decompressed | {more, Decompressed} when 320 Z :: zstream(), 321 Data :: iodata(), 322 Decompressed :: iolist(). 323inflateChunk(Z, Data) -> 324 enqueue_input(Z, Data), 325 inflateChunk(Z). 326 327-spec inflateChunk(Z) -> Decompressed | {more, Decompressed} when 328 Z :: zstream(), 329 Decompressed :: iolist(). 330inflateChunk(Z) -> 331 Opts0 = inflate_opts(), 332 Opts = Opts0#zlib_opts { output_chunk_size = getBufSize(Z) }, 333 334 Result0 = dequeue_next_chunk(Z, Opts), 335 Result1 = exception_on_need_dict(Z, Result0), 336 yield_inflateChunk(Z, Result1). 337 338yield_inflateChunk(_Z, {continue, Output}) -> 339 {more, lists:flatten(Output)}; 340yield_inflateChunk(_Z, {finished, Output}) -> 341 lists:flatten(Output). 342 343exception_on_need_dict(Z, {need_dictionary, Adler, Output}) -> 344 Progress = restore_progress(Z, inflate), 345 save_progress(Z, inflate, append_iolist(Progress, Output)), 346 erlang:error({need_dictionary, Adler}); 347exception_on_need_dict(Z, {Mark, Output}) -> 348 Progress = restore_progress(Z, inflate), 349 {Mark, append_iolist(Progress, Output)}; 350exception_on_need_dict(Z, Output) when is_list(Output); is_binary(Output) -> 351 Progress = restore_progress(Z, inflate), 352 append_iolist(Progress, Output). 353 354-spec safeInflate(Z, Data) -> Result when 355 Z :: zstream(), 356 Data :: iodata(), 357 Result :: {continue, Output :: iolist()} | 358 {finished, Output :: iolist()} | 359 {need_dictionary, 360 Adler32 :: non_neg_integer(), 361 Output :: iolist()}. 362safeInflate(Z, Data) -> 363 enqueue_input(Z, Data), 364 dequeue_next_chunk(Z, inflate_opts()). 365 366-spec inflateEnd(Z) -> 'ok' when 367 Z :: zstream(). 368inflateEnd(Z) -> 369 inflateEnd_nif(Z). 370inflateEnd_nif(_Z) -> 371 erlang:nif_error(undef). 372 373-spec setBufSize(Z, Size) -> 'ok' when 374 Z :: zstream(), 375 Size :: non_neg_integer(). 376setBufSize(Z, Size) when is_integer(Size), Size > 16, Size < (1 bsl 24) -> 377 setBufSize_nif(Z, Size); 378setBufSize(_Z, _Size) -> 379 erlang:error(badarg). 380setBufSize_nif(_Z, _Size) -> 381 erlang:nif_error(undef). 382 383-spec getBufSize(Z) -> non_neg_integer() when 384 Z :: zstream(). 385getBufSize(Z) -> 386 getBufSize_nif(Z). 387getBufSize_nif(_Z) -> 388 erlang:nif_error(undef). 389 390-spec crc32(Z) -> CRC when 391 Z :: zstream(), 392 CRC :: non_neg_integer(). 393crc32(Z) -> 394 crc32_nif(Z). 395crc32_nif(_Z) -> 396 erlang:nif_error(undef). 397 398-spec crc32(Z, Data) -> CRC when 399 Z :: zstream(), 400 Data :: iodata(), 401 CRC :: non_neg_integer(). 402crc32(Z, Data) when is_reference(Z) -> 403 erlang:crc32(Data); 404crc32(_Z, _Data) -> 405 erlang:error(badarg). 406 407-spec crc32(Z, PrevCRC, Data) -> CRC when 408 Z :: zstream(), 409 PrevCRC :: non_neg_integer(), 410 Data :: iodata(), 411 CRC :: non_neg_integer(). 412crc32(Z, CRC, Data) when is_reference(Z) -> 413 erlang:crc32(CRC, Data); 414crc32(_Z, _CRC, _Data) -> 415 erlang:error(badarg). 416 417-spec crc32_combine(Z, CRC1, CRC2, Size2) -> CRC when 418 Z :: zstream(), 419 CRC :: non_neg_integer(), 420 CRC1 :: non_neg_integer(), 421 CRC2 :: non_neg_integer(), 422 Size2 :: non_neg_integer(). 423crc32_combine(Z, CRC1, CRC2, Size2) when is_reference(Z) -> 424 erlang:crc32_combine(CRC1, CRC2, Size2); 425crc32_combine(_Z, _CRC1, _CRC2, _Size2) -> 426 erlang:error(badarg). 427 428-spec adler32(Z, Data) -> CheckSum when 429 Z :: zstream(), 430 Data :: iodata(), 431 CheckSum :: non_neg_integer(). 432adler32(Z, Data) when is_reference(Z) -> 433 erlang:adler32(Data); 434adler32(_Z, _Data) -> 435 erlang:error(badarg). 436 437-spec adler32(Z, PrevAdler, Data) -> CheckSum when 438 Z :: zstream(), 439 PrevAdler :: non_neg_integer(), 440 Data :: iodata(), 441 CheckSum :: non_neg_integer(). 442adler32(Z, Adler, Data) when is_reference(Z) -> 443 erlang:adler32(Adler, Data); 444adler32(_Z, _Adler, _Data) -> 445 erlang:error(badarg). 446 447-spec adler32_combine(Z, Adler1, Adler2, Size2) -> Adler when 448 Z :: zstream(), 449 Adler :: non_neg_integer(), 450 Adler1 :: non_neg_integer(), 451 Adler2 :: non_neg_integer(), 452 Size2 :: non_neg_integer(). 453adler32_combine(Z, Adler1, Adler2, Size2) when is_reference(Z) -> 454 erlang:adler32_combine(Adler1, Adler2, Size2); 455adler32_combine(_Z, _Adler1, _Adler2, _Size2) -> 456 erlang:error(badarg). 457 458%% compress/uncompress zlib with header 459-spec compress(Data) -> Compressed when 460 Data :: iodata(), 461 Compressed :: binary(). 462compress(Data) -> 463 Z = open(), 464 Bs = try 465 deflateInit(Z, default), 466 B = deflate(Z, Data, finish), 467 deflateEnd(Z), 468 B 469 after 470 close(Z) 471 end, 472 iolist_to_binary(Bs). 473 474-spec uncompress(Data) -> Decompressed when 475 Data :: iodata(), 476 Decompressed :: binary(). 477uncompress(Data) -> 478 try iolist_size(Data) of 479 Size -> 480 if 481 Size >= 8 -> 482 Z = open(), 483 Bs = try 484 inflateInit(Z), 485 B = inflate(Z, Data), 486 inflateEnd(Z), 487 B 488 after 489 close(Z) 490 end, 491 iolist_to_binary(Bs); 492 true -> 493 erlang:error(data_error) 494 end 495 catch 496 _:_ -> 497 erlang:error(badarg) 498 end. 499 500%% unzip/zip zlib without header (zip members) 501-spec zip(Data) -> Compressed when 502 Data :: iodata(), 503 Compressed :: binary(). 504zip(Data) -> 505 Z = open(), 506 Bs = try 507 deflateInit(Z, default, deflated, -?MAX_WBITS, 8, default), 508 B = deflate(Z, Data, finish), 509 deflateEnd(Z), 510 B 511 after 512 close(Z) 513 end, 514 iolist_to_binary(Bs). 515 516-spec unzip(Data) -> Decompressed when 517 Data :: iodata(), 518 Decompressed :: binary(). 519unzip(Data) -> 520 Z = open(), 521 Bs = try 522 inflateInit(Z, -?MAX_WBITS), 523 B = inflate(Z, Data), 524 inflateEnd(Z), 525 B 526 after 527 close(Z) 528 end, 529 iolist_to_binary(Bs). 530 531-spec gzip(Data) -> Compressed when 532 Data :: iodata(), 533 Compressed :: binary(). 534gzip(Data) -> 535 Z = open(), 536 Bs = try 537 deflateInit(Z, default, deflated, 16+?MAX_WBITS, 8, default), 538 B = deflate(Z, Data, finish), 539 deflateEnd(Z), 540 B 541 after 542 close(Z) 543 end, 544 iolist_to_binary(Bs). 545 546-spec gunzip(Data) -> Decompressed when 547 Data :: iodata(), 548 Decompressed :: binary(). 549gunzip(Data) -> 550 Z = open(), 551 Bs = try 552 inflateInit(Z, 16+?MAX_WBITS, reset), 553 B = inflate(Z, Data), 554 inflateEnd(Z), 555 B 556 after 557 close(Z) 558 end, 559 iolist_to_binary(Bs). 560 561-spec dequeue_all_chunks(Z, Opts) -> Result when 562 Z :: zstream(), 563 Opts :: #zlib_opts{}, 564 Result :: {need_dictionary, integer(), iolist()} | 565 iolist(). 566dequeue_all_chunks(Z, Opts) -> 567 dequeue_all_chunks_1(Z, Opts, []). 568dequeue_all_chunks_1(Z, Opts, Output) -> 569 case dequeue_next_chunk(Z, Opts) of 570 {need_dictionary, _, _} = NeedDict -> 571 NeedDict; 572 {continue, Chunk} -> 573 dequeue_all_chunks_1(Z, Opts, append_iolist(Output, Chunk)); 574 {finished, Chunk} -> 575 append_iolist(Output, Chunk) 576 end. 577 578-spec dequeue_next_chunk(Z, Opts) -> Result when 579 Z :: zstream(), 580 Opts :: #zlib_opts{}, 581 Result :: {need_dictionary, integer(), iolist()} | 582 {continue, iolist()} | 583 {finished, iolist()}. 584dequeue_next_chunk(Z, Opts) -> 585 Method = Opts#zlib_opts.method, 586 IChSz = Opts#zlib_opts.input_chunk_size, 587 OChSz = Opts#zlib_opts.output_chunk_size, 588 Flush = Opts#zlib_opts.flush, 589 Method(Z, IChSz, OChSz, Flush). 590 591-spec append_iolist(IO, D) -> iolist() when 592 IO :: iodata(), 593 D :: iodata(). 594append_iolist([], D) when is_list(D) -> D; 595append_iolist([], D) -> [D]; 596append_iolist(IO, []) -> IO; 597append_iolist(IO, [D]) -> [IO, D]; 598append_iolist(IO, D) -> [IO, D]. 599 600%% inflate/2 and friends are documented as throwing an error on Z_NEED_DICT 601%% rather than simply returning something to that effect, and deflateParams/3 602%% may flush behind the scenes. This requires us to stow away our current 603%% progress in the handle and resume from that point on our next call. 604%% 605%% Generally speaking this is either a refc binary or nothing at all, so it's 606%% pretty cheap. 607 608-spec save_progress(Z, Kind, Output) -> ok when 609 Z :: zstream(), 610 Kind :: inflate | deflate, 611 Output :: iolist(). 612save_progress(Z, Kind, Output) -> 613 ok = setStash_nif(Z, {Kind, Output}). 614 615-spec restore_progress(Z, Kind) -> iolist() when 616 Z :: zstream(), 617 Kind :: inflate | deflate. 618restore_progress(Z, Kind) -> 619 case getStash_nif(Z) of 620 {ok, {Kind, Output}} -> 621 ok = clearStash_nif(Z), 622 Output; 623 empty -> 624 [] 625 end. 626 627-spec clearStash_nif(Z) -> ok when 628 Z :: zstream(). 629clearStash_nif(_Z) -> 630 erlang:nif_error(undef). 631 632-spec setStash_nif(Z, Term) -> ok when 633 Z :: zstream(), 634 Term :: term(). 635setStash_nif(_Z, _Term) -> 636 erlang:nif_error(undef). 637 638-spec getStash_nif(Z) -> {ok, term()} | empty when 639 Z :: zstream(). 640getStash_nif(_Z) -> 641 erlang:nif_error(undef). 642 643%% The 'proplists' module isn't preloaded so we can't rely on its existence. 644proplist_get_value([], _Name, DefVal) -> DefVal; 645proplist_get_value([{Name, Value} | _Opts], Name, _DefVal) -> Value; 646proplist_get_value([_Head | Opts], Name, DefVal) -> 647 proplist_get_value(Opts, Name, DefVal). 648 649arg_flush(none) -> ?Z_NO_FLUSH; 650%% ?Z_PARTIAL_FLUSH is deprecated in zlib -- deliberately not included. 651arg_flush(sync) -> ?Z_SYNC_FLUSH; 652arg_flush(full) -> ?Z_FULL_FLUSH; 653arg_flush(finish) -> ?Z_FINISH; 654arg_flush(_) -> erlang:error(bad_flush_mode). 655 656arg_level(none) -> ?Z_NO_COMPRESSION; 657arg_level(best_speed) -> ?Z_BEST_SPEED; 658arg_level(best_compression) -> ?Z_BEST_COMPRESSION; 659arg_level(default) -> ?Z_DEFAULT_COMPRESSION; 660arg_level(Level) when is_integer(Level), Level >= 0, Level =< 9 -> Level; 661arg_level(_) -> erlang:error(bad_compression_level). 662 663arg_strategy(filtered) -> ?Z_FILTERED; 664arg_strategy(huffman_only) -> ?Z_HUFFMAN_ONLY; 665arg_strategy(rle) -> ?Z_RLE; 666arg_strategy(default) -> ?Z_DEFAULT_STRATEGY; 667arg_strategy(_) -> erlang:error(bad_compression_strategy). 668 669arg_method(deflated) -> ?Z_DEFLATED; 670arg_method(_) -> erlang:error(bad_compression_method). 671 672arg_eos_behavior(error) -> ?EOS_BEHAVIOR_ERROR; 673arg_eos_behavior(reset) -> ?EOS_BEHAVIOR_RESET; 674arg_eos_behavior(cut) -> ?EOS_BEHAVIOR_CUT; 675arg_eos_behavior(_) -> erlang:error(bad_eos_behavior). 676 677-spec arg_bitsz(zwindowbits()) -> zwindowbits(). 678arg_bitsz(Bits) when is_integer(Bits) andalso 679 ((8 =< Bits andalso Bits < 48) orelse 680 (-15 =< Bits andalso Bits =< -8)) -> 681 Bits; 682arg_bitsz(_) -> erlang:error(bad_windowbits). 683 684-spec arg_mem(zmemlevel()) -> zmemlevel(). 685arg_mem(Level) when is_integer(Level), 1 =< Level, Level =< 9 -> Level; 686arg_mem(_) -> erlang:error(bad_memlevel). 687 688-spec enqueue_input(Z, IOData) -> ok when 689 Z :: zstream(), 690 IOData :: iodata(). 691enqueue_input(Z, IOData) -> 692 enqueue_input_1(Z, erlang:iolist_to_iovec(IOData)). 693 694enqueue_input_1(_Z, []) -> 695 ok; 696enqueue_input_1(Z, IOVec) -> 697 case enqueue_nif(Z, IOVec) of 698 {continue, Remainder} -> enqueue_input_1(Z, Remainder); 699 ok -> ok 700 end. 701 702enqueue_nif(_Z, _IOVec) -> 703 erlang:nif_error(undef). 704