From 43093a22099f6b0ec33970163a40f42a6b70b978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Tue, 5 Feb 2013 10:10:45 +0100 Subject: prim_file: Refactor handling of responses Currently, the format of the return value from drv_command/3 is determined solely by the efile driver's response. In a future commit, we will need to produce different return values that also dependend on which function in prim_file that was called; thus, we will need some way to pass down some sort of state to drv_get_response/2. As a preparation for that, allow the third argument of drv_command/3 to be a fun. That also allows us to remove the convoluted special case handling of the list_dir operation. --- erts/preloaded/src/prim_file.erl | 55 +++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) (limited to 'erts/preloaded/src') diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 71ec97eb89..e1d42a4b9a 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -899,9 +899,30 @@ list_dir(Port, Dir) when is_port(Port) -> list_dir_int(Port, Dir). list_dir_int(Port, Dir) -> - drv_command(Port, [?FILE_READDIR, pathname(Dir)], []). - + drv_command(Port, [?FILE_READDIR, pathname(Dir)], + fun(P) -> + case list_dir_response(P, []) of + {ok, RawNames} -> + {ok, list_dir_convert(RawNames)}; + Error -> + Error + end + end). + +list_dir_response(Port, Acc0) -> + case drv_get_response(Port) of + {lfname, []} -> + {ok, Acc0}; + {lfname, Names} -> + Acc = [Name || <> <= Names] ++ Acc0, + list_dir_response(Port, Acc); + Error -> + Error + end. +list_dir_convert([Name|Names]) -> + [prim_file:internal_native2name(Name)|list_dir_convert(Names)]; +list_dir_convert([]) -> []. %%%----------------------------------------------------------------- %%% Functions to communicate with the driver @@ -1017,19 +1038,10 @@ drv_command_nt(Port, Command, R) when is_port(Port) -> %% Receives the response from a driver port. %% Returns: {ok, ListOrBinary}|{error, Reason} -drv_get_response(Port, R) when is_list(R) -> - case drv_get_response(Port) of - ok -> - {ok, R}; - {ok, Name} -> - drv_get_response(Port, [Name|R]); - {append, Names} -> - drv_get_response(Port, append(Names, R)); - Error -> - Error - end; -drv_get_response(Port, _) -> - drv_get_response(Port). +drv_get_response(Port, undefined) -> + drv_get_response(Port); +drv_get_response(Port, Fun) when is_function(Fun, 1) -> + Fun(Port). drv_get_response(Port) -> erlang:bump_reductions(100), @@ -1049,10 +1061,6 @@ drv_get_response(Port) -> %%%----------------------------------------------------------------- %%% Utility functions. -append([I | Is], R) when is_list(R) -> append(Is, [I | R]); -append([], R) -> R. - - %% Converts a list of mode atoms into a mode word for the driver. %% Returns {Mode, Portopts, Setopts} where Portopts is a list of %% options for erlang:open_port/2 and Setopts is a list of @@ -1196,10 +1204,8 @@ translate_response(?FILE_RESP_EOF, []) -> eof; translate_response(?FILE_RESP_FNAME, Data) when is_binary(Data) -> {ok, prim_file:internal_native2name(Data)}; -translate_response(?FILE_RESP_LFNAME, []) -> - ok; -translate_response(?FILE_RESP_LFNAME, Data) when is_binary(Data) -> - {append, transform_lfname(Data)}; +translate_response(?FILE_RESP_LFNAME, Data) -> + {lfname, Data}; translate_response(?FILE_RESP_ALL_DATA, Data) -> {ok, Data}; translate_response(X, Data) -> @@ -1315,9 +1321,6 @@ transform_ldata(0, List, [Size | Sizes], R) -> {Front, Rear} = lists_split(List, Size), transform_ldata(0, Rear, Sizes, [Front | R]). -transform_lfname(Names) -> - [prim_file:internal_native2name(Name) || <> <= Names]. - lists_split(List, 0) when is_list(List) -> {[], List}; lists_split(List, N) when is_list(List), is_integer(N), N < 0 -> -- cgit v1.2.3