[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