aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2013-02-05 10:10:45 +0100
committerBjörn Gustavsson <[email protected]>2013-02-11 14:09:27 +0100
commit43093a22099f6b0ec33970163a40f42a6b70b978 (patch)
treedc017e5ae53fdb623e38aceb99a4db13a04e80ef
parentb00651f9701f6d352b270af3700abce0e65aa5b6 (diff)
downloadotp-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.erl55
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 ->