zlib.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 337 行
ERL
337 行
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Tony Rogvall.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%-module(zlib).-export([open/0,close/1,deflateInit/1,deflateInit/2,deflateInit/6, deflateSetDictionary/2,deflateReset/1,deflateParams/3, deflate/2,deflate/3,deflateEnd/1, inflateInit/1,inflateInit/2,inflateSetDictionary/2, inflateSync/1,inflateReset/1,inflate/2,inflateEnd/1, setBufSize/2,getBufSize/1, crc32/1,crc32/2,crc32/3,adler32/2,adler32/3,getQSize/1, compress/1,uncompress/1,zip/1,unzip/1, gzip/1,gunzip/1]).%% flush argument encoding-define(Z_NO_FLUSH, 0).-define(Z_SYNC_FLUSH, 2).-define(Z_FULL_FLUSH, 3).-define(Z_FINISH, 4).%% compression level-define(Z_NO_COMPRESSION, 0).-define(Z_BEST_SPEED, 1).-define(Z_BEST_COMPRESSION, 9).-define(Z_DEFAULT_COMPRESSION, (-1)).%% compresssion strategy-define(Z_FILTERED, 1).-define(Z_HUFFMAN_ONLY, 2).-define(Z_DEFAULT_STRATEGY, 0).%% deflate compression method-define(Z_DEFLATED, 8).-define(Z_NULL, 0).-define(MAX_WBITS, 15).%% gzip defs (rfc 1952)-define(ID1, 16#1f).-define(ID2, 16#8b).-define(FTEXT, 16#01).-define(FHCRC, 16#02).-define(FEXTRA, 16#04).-define(FNAME, 16#08).-define(FCOMMENT, 16#10).-define(RESERVED, 16#E0).-define(OS_MDDOS, 0).-define(OS_AMIGA, 1).-define(OS_OPENVMS, 2).-define(OS_UNIX, 3).-define(OS_VMCMS, 4).-define(OS_ATARI, 5).-define(OS_OS2, 6).-define(OS_MAC, 7).-define(OS_ZSYS, 8).-define(OS_CPM, 9).-define(OS_TOP20, 10).-define(OS_NTFS, 11).-define(OS_QDOS, 12).-define(OS_ACORN, 13).-define(OS_UNKNOWN,255).-define(DEFLATE_INIT, 1).-define(DEFLATE_INIT2, 2).-define(DEFLATE_SETDICT, 3).-define(DEFLATE_RESET, 4).-define(DEFLATE_END, 5).-define(DEFLATE_PARAMS, 6).-define(DEFLATE, 7).-define(INFLATE_INIT, 8).-define(INFLATE_INIT2, 9).-define(INFLATE_SETDICT, 10).-define(INFLATE_SYNC, 11).-define(INFLATE_RESET, 12).-define(INFLATE_END, 13).-define(INFLATE, 14).-define(CRC32_0, 15).-define(CRC32_1, 16).-define(CRC32_2, 17).-define(SET_BUFSZ, 18).-define(GET_BUFSZ, 19).-define(GET_QSIZE, 20).-define(ADLER32_1, 21).-define(ADLER32_2, 22).%% open a z_streamopen() -> open_port({spawn, zlib_drv}, [binary]).%% close and release z_streamclose(Z) -> try true = port_close(Z), ok catch _:_ -> erlang:error(badarg) end.deflateInit(Z) -> call(Z, ?DEFLATE_INIT, <<?Z_DEFAULT_COMPRESSION:32>>).deflateInit(Z, Level) -> call(Z, ?DEFLATE_INIT, <<(arg_level(Level)):32>>).deflateInit(Z, Level, Method, WindowBits, MemLevel, Strategy) -> call(Z, ?DEFLATE_INIT2, <<(arg_level(Level)):32, (arg_method(Method)):32, (arg_bitsz(WindowBits)):32, (arg_mem(MemLevel)):32, (arg_strategy(Strategy)):32>>).deflateSetDictionary(Z, Dictionary) -> call(Z, ?DEFLATE_SETDICT, Dictionary).deflateReset(Z) -> call(Z, ?DEFLATE_RESET, []).deflateParams(Z, Level, Strategy) -> call(Z, ?DEFLATE_PARAMS, <<(arg_level(Level)):32, (arg_strategy(Strategy)):32>>).deflate(Z, Data) -> deflate(Z, Data, none).deflate(Z, Data, Flush) -> try port_command(Z, Data) of true -> call(Z, ?DEFLATE, <<(arg_flush(Flush)):32>>), collect(Z) catch error:_Err -> flush(Z), erlang:error(badarg) end.deflateEnd(Z) -> call(Z, ?DEFLATE_END, []). inflateInit(Z) -> call(Z, ?INFLATE_INIT, []). inflateInit(Z, WindowBits) -> call(Z, ?INFLATE_INIT2, <<(arg_bitsz(WindowBits)):32>>).inflateSetDictionary(Z, Dictionary) -> call(Z, ?INFLATE_SETDICT, Dictionary).inflateSync(Z) -> call(Z, ?INFLATE_SYNC, []).inflateReset(Z) -> call(Z, ?INFLATE_RESET, []). inflate(Z, Data) -> try port_command(Z, Data) of true -> call(Z, ?INFLATE, <<?Z_NO_FLUSH:32>>), collect(Z) catch error:_Err -> flush(Z), erlang:error(badarg) end.inflateEnd(Z) -> call(Z, ?INFLATE_END, []).setBufSize(Z, Size) -> call(Z, ?SET_BUFSZ, <<Size:32>>).getBufSize(Z) -> call(Z, ?GET_BUFSZ, []).crc32(Z) -> call(Z, ?CRC32_0, []).crc32(Z, Binary) -> call(Z, ?CRC32_1, Binary).crc32(Z, CRC, Binary) when is_binary(Binary), is_integer(CRC) -> call(Z, ?CRC32_2, <<CRC:32, Binary/binary>>);crc32(_Z, _CRC, _Binary) -> erlang:error(badarg).adler32(Z, Binary) -> call(Z, ?ADLER32_1, Binary).adler32(Z, Adler, Binary) when is_binary(Binary), is_integer(Adler) -> call(Z, ?ADLER32_2, <<Adler:32, Binary/binary>>);adler32(_Z, _Adler, _Binary) -> erlang:error(badarg).getQSize(Z) -> call(Z, ?GET_QSIZE, []). %% compress/uncompress zlib with headercompress(Binary) -> Z = open(), deflateInit(Z, default), Bs = deflate(Z, Binary,finish), deflateEnd(Z), close(Z), list_to_binary(Bs).uncompress(Binary) when is_binary(Binary), size(Binary) >= 8 -> Z = open(), inflateInit(Z), Bs = inflate(Z, Binary), inflateEnd(Z), close(Z), list_to_binary(Bs);uncompress(Binary) when is_binary(Binary) -> erlang:error(data_error);uncompress(_) -> erlang:error(badarg).%% unzip/zip zlib without header (zip members)zip(Binary) -> Z = open(), deflateInit(Z, default, deflated, -?MAX_WBITS, 8, default), Bs = deflate(Z, Binary, finish), deflateEnd(Z), close(Z), list_to_binary(Bs).unzip(Binary) -> Z = open(), inflateInit(Z, -?MAX_WBITS), Bs = inflate(Z, Binary), inflateEnd(Z), close(Z), list_to_binary(Bs). gzip(Data) when is_binary(Data); is_list(Data) -> Z = open(), deflateInit(Z, default, deflated, 16+?MAX_WBITS, 8, default), Bs = deflate(Z, Data, finish), deflateEnd(Z), close(Z), iolist_to_binary(Bs);gzip(_) -> erlang:error(badarg).gunzip(Data) when is_binary(Data); is_list(Data) -> Z = open(), inflateInit(Z, 16+?MAX_WBITS), Bs = inflate(Z, Data), inflateEnd(Z), close(Z), iolist_to_binary(Bs);gunzip(_) -> erlang:error(badarg).collect(Z) -> collect(Z,[]).collect(Z,Acc) -> receive {Z, {data, Bin}} -> collect(Z,[Bin|Acc]) after 0 -> lists:reverse(Acc) end.flush(Z) -> receive {Z, {data,_}} -> flush(Z) after 0 -> ok end. arg_flush(none) -> ?Z_NO_FLUSH;%% ?Z_PARTIAL_FLUSH is deprecated in zlib -- deliberately not included.arg_flush(sync) -> ?Z_SYNC_FLUSH;arg_flush(full) -> ?Z_FULL_FLUSH;arg_flush(finish) -> ?Z_FINISH;arg_flush(_) -> erlang:error(badarg).arg_level(none) -> ?Z_NO_COMPRESSION;arg_level(best_speed) -> ?Z_BEST_SPEED;arg_level(best_compression) -> ?Z_BEST_COMPRESSION;arg_level(default) -> ?Z_DEFAULT_COMPRESSION;arg_level(Level) when is_integer(Level), Level >= 0, Level =< 9 -> Level;arg_level(_) -> erlang:error(badarg). arg_strategy(filtered) -> ?Z_FILTERED;arg_strategy(huffman_only) -> ?Z_HUFFMAN_ONLY;arg_strategy(default) -> ?Z_DEFAULT_STRATEGY;arg_strategy(_) -> erlang:error(badarg).arg_method(deflated) -> ?Z_DEFLATED;arg_method(_) -> erlang:error(badarg).arg_bitsz(Bits) when is_integer(Bits) andalso ((8 < Bits andalso Bits < 48) orelse (-15 =< Bits andalso Bits < -8)) -> Bits;arg_bitsz(_) -> erlang:error(badarg).arg_mem(Level) when is_integer(Level), 1 =< Level, Level =< 9 -> Level;arg_mem(_) -> erlang:error(badarg).call(Z, Cmd, Arg) -> try port_control(Z, Cmd, Arg) of [0|Res] -> list_to_atom(Res); [1|Res] -> flush(Z), erlang:error(list_to_atom(Res)); [2,A,B,C,D] -> (A bsl 24)+(B bsl 16)+(C bsl 8)+D; [3,A,B,C,D] -> erlang:error({need_dictionary,(A bsl 24)+(B bsl 16)+(C bsl 8)+D}) catch error:badarg -> %% Rethrow loses port_control from stacktrace. erlang:error(badarg) end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?