diff options
author | Björn Gustavsson <[email protected]> | 2013-02-05 10:10:45 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2013-02-11 14:09:27 +0100 |
commit | 43093a22099f6b0ec33970163a40f42a6b70b978 (patch) | |
tree | dc017e5ae53fdb623e38aceb99a4db13a04e80ef | |
parent | b00651f9701f6d352b270af3700abce0e65aa5b6 (diff) | |
download | otp-43093a22099f6b0ec33970163a40f42a6b70b978.tar.gz otp-43093a22099f6b0ec33970163a40f42a6b70b978.tar.bz2 otp-43093a22099f6b0ec33970163a40f42a6b70b978.zip |
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.
-rw-r--r-- | erts/preloaded/src/prim_file.erl | 55 |
1 files changed, 29 insertions, 26 deletions
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 || <<L:16,Name:L/binary>> <= 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) || <<L:16,Name:L/binary>> <= Names]. - lists_split(List, 0) when is_list(List) -> {[], List}; lists_split(List, N) when is_list(List), is_integer(N), N < 0 -> |