[m-rev.] diff: io.read_file_as_string for erlang backend
Peter Wang
wangp at students.csse.unimelb.edu.au
Fri Aug 17 11:42:10 AEST 2007
Estimated hours taken: 1
Branches: main
library/io.m:
Implement io.read_file_as_string efficiently for Erlang.
Implement io.stream_file_size for Erlang.
Index: library/io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.400
diff -u -r1.400 io.m
--- library/io.m 3 Aug 2007 02:30:39 -0000 1.400
+++ library/io.m 17 Aug 2007 01:36:50 -0000
@@ -2287,6 +2287,14 @@
io.input_stream(Stream, !IO),
io.read_file_as_string(Stream, Result, !IO).
+:- pragma foreign_proc("Erlang",
+ io.read_file_as_string(InputStream::in, Result::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ {input_stream, Stream} = InputStream,
+ Result = mercury__io:mercury_read_string_to_eof(Stream)
+").
+
io.read_file_as_string(Stream, Result, !IO) :-
% Check if the stream is a regular file; if so, allocate a buffer
% according to the size of the file. Otherwise, just use a default buffer
@@ -2766,6 +2774,20 @@
Size = Stream.size();
").
+:- pragma foreign_proc("Erlang",
+ io.stream_file_size(Stream::in, Size::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ OrigPos = mercury_seek(Stream, cur),
+ if
+ OrigPos >= 0 ->
+ Size = mercury_seek(Stream, eof),
+ mercury_seek(Stream, {bof, OrigPos});
+ true ->
+ Size = -1
+ end
+").
+
io.file_modification_time(File, Result, !IO) :-
io.file_modification_time_2(File, Status, Msg, Time, !IO),
( Status = 1 ->
@@ -6203,6 +6225,7 @@
mercury_open_stream/2,
mercury_close_stream/1,
mercury_getc/1,
+ mercury_read_string_to_eof/1,
mercury_putback/2,
mercury_write_string/2,
mercury_write_char/2,
@@ -6266,6 +6289,25 @@
From ! {self(), read_char_ack, Ret},
mercury_file_server(IoDevice, LineNr, PutBack)
;
+ {From, read_string_to_eof} ->
+ % Grab everything from the putback buffer.
+ Pre = lists:reverse(PutBack0),
+ PutBack = [],
+
+ % Read everything to EOF.
+ case mercury_read_file_to_eof_2(IoDevice, []) of
+ {ok, String} ->
+ PrePlusString = Pre ++ String,
+ Ret = {ok, PrePlusString},
+ LineNr = LineNr0 + count_nls(PrePlusString, 0);
+ {error, Reason} ->
+ Ret = {error, Pre, Reason},
+ LineNr = LineNr0 + count_nls(Pre, 0)
+ end,
+
+ From ! {self(), read_string_to_eof_ack, Ret},
+ mercury_file_server(IoDevice, LineNr, PutBack)
+ ;
{From, putback, Char} ->
From ! {self(), putback_ack},
PutBack = [Char | PutBack0],
@@ -6324,6 +6366,17 @@
mercury_file_server(IoDevice, LineNr0, PutBack0)
end.
+mercury_read_file_to_eof_2(IoDevice, Acc) ->
+ ChunkSize = 65536,
+ case file:read(IoDevice, ChunkSize) of
+ {ok, Chunk} ->
+ mercury_read_file_to_eof_2(IoDevice, [Chunk | Acc]);
+ eof ->
+ {ok, lists:flatten(lists:reverse(Acc))};
+ {error, Reason} ->
+ {error, Acc, Reason}
+ end.
+
one_if_nl($\\n) -> 1;
one_if_nl(_) -> 0.
@@ -6378,6 +6431,20 @@
end
end.
+mercury_read_string_to_eof(Stream) ->
+ {'ML_stream', _Id, Pid} = Stream,
+ Pid ! {self(), read_string_to_eof},
+ receive
+ {Pid, read_string_to_eof_ack, Ret} ->
+ case Ret of
+ {error, _Partial, Reason} ->
+ put('MR_io_exception', Reason);
+ _ ->
+ void
+ end,
+ Ret
+ end.
+
mercury_putback(Stream, Character) ->
{'ML_stream', _Id, Pid} = Stream,
Pid ! {self(), putback, Character},
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list