[m-rev.] for review: add some unboxed readers fro binary input streams

Julien Fischer jfischer at opturion.com
Mon Oct 11 00:39:56 AEDT 2021


For review by anyone.

-------------------------

Add some unboxed readers for binary input streams.

library/io.m:
     Add unboxed versions of the predicates for reading binary
     int8s and uint8s.

     Define instances of the unboxed_reader type class for
     binary input streams and int8s / uint8s.

NEWS:
     Announce the new predicates.

Julien.

diff --git a/NEWS b/NEWS
index 58058c9..adb6128 100644
--- a/NEWS
+++ b/NEWS
@@ -163,6 +163,8 @@ Changes to the Mercury standard library
  * The following predicates have been added to this module:

      - pred `get_environment_var_map/3`
+    - pred `read_binary_int8_unboxed/5`
+    - pred `read_binary_uint8_unboxed/5`
      - pred `read_named_file_as_string/4`
      - pred `read_named_file_as_lines/4`
      - pred `write_line_cc/4`
diff --git a/library/io.m b/library/io.m
index 3859e97..303b3d2 100644
--- a/library/io.m
+++ b/library/io.m
@@ -592,6 +592,13 @@
  :- pred read_binary_int8(io.binary_input_stream::in, io.result(int8)::out,
      io::di, io::uo) is det.

+    % Reads a single signed 8-bit integer from the specified binary input
+    % stream. This interface avoids memory allocation when there is no error.
+    %
+:- pred read_binary_int8_unboxed(io.binary_input_stream::in, io.result::out,
+    int8::out, io::di, io::uo) is det.
+% NOTE_TO_IMPLEMENTORS there is no version without an explicit stream argument
+
      % Reads a single unsigned 8-bit integer from the current binary input
      % stream or from the specified binary input stream.
      %
@@ -599,6 +606,13 @@
  :- pred read_binary_uint8(io.binary_input_stream::in, io.result(uint8)::out,
      io::di, io::uo) is det.

+    % Reads a single unsigned 8-bit integer from the specified binary input
+    % stream. This interface avoids memory allocation when there is no error.
+    %
+:- pred read_binary_uint8_unboxed(io.binary_input_stream::in, io.result::out,
+    uint8::out, io::di, io::uo) is det.
+% NOTE_TO_IMPLEMENTORS there is no version without an explicit stream argument
+
  %---------------------%

      % Un-reads a byte from the current binary input stream or from the
@@ -2024,6 +2038,8 @@
  :- instance stream.reader(binary_input_stream, int, io, io.error).
  :- instance stream.reader(binary_input_stream, int8, io, io.error).
  :- instance stream.reader(binary_input_stream, uint8, io, io.error).
+:- instance stream.unboxed_reader(binary_input_stream, int8, io, io.error).
+:- instance stream.unboxed_reader(binary_input_stream, uint8, io, io.error).
  :- instance stream.bulk_reader(binary_input_stream, int, bitmap, io, io.error).
  :- instance stream.putback(binary_input_stream, int, io, io.error).
  :- instance stream.putback(binary_input_stream, int8, io, io.error).
@@ -2570,6 +2586,24 @@ result0_to_stream_result0(error(Error)) = error(Error).
      )
  ].

+:- instance stream.unboxed_reader(binary_input_stream, int8, io, io.error)
+    where
+[
+    ( unboxed_get(Stream, Result, Int8, !IO) :-
+        read_binary_int8_unboxed(Stream, Result0, Int8, !IO),
+        Result = io.result0_to_stream_result0(Result0)
+    )
+].
+
+:- instance stream.unboxed_reader(binary_input_stream, uint8, io, io.error)
+    where
+[
+    ( unboxed_get(Stream, Result, UInt8, !IO) :-
+        read_binary_uint8_unboxed(Stream, Result0, UInt8, !IO),
+        Result = io.result0_to_stream_result0(Result0)
+    )
+].
+
  :- instance stream.bulk_reader(binary_input_stream, int,
          bitmap, io, io.error)
      where
@@ -5690,6 +5724,21 @@ read_binary_int8(binary_input_stream(Stream), Result, !IO) :-
          Result = error(io_error(Msg))
      ).

+read_binary_int8_unboxed(binary_input_stream(Stream), Result, Int8, !IO) :-
+    read_byte_val(input_stream(Stream), ResultCode, Int, Error, !IO),
+    Int8 = cast_from_int(Int),
+    (
+        ResultCode = result_code_ok,
+        Result = ok
+    ;
+        ResultCode = result_code_eof,
+        Result = eof
+    ;
+        ResultCode = result_code_error,
+        make_err_msg(Error, "read failed: ", Msg, !IO),
+        Result = error(io_error(Msg))
+    ).
+
  read_binary_uint8(Result, !IO) :-
      binary_input_stream(Stream, !IO),
      read_binary_uint8(Stream, Result, !IO).
@@ -5709,6 +5758,21 @@ read_binary_uint8(binary_input_stream(Stream), Result, !IO) :-
          Result = error(io_error(Msg))
      ).

+read_binary_uint8_unboxed(binary_input_stream(Stream), Result, UInt8, !IO) :-
+    read_byte_val(input_stream(Stream), ResultCode, Int, Error, !IO),
+    UInt8 = cast_from_int(Int),
+    (
+        ResultCode = result_code_ok,
+        Result = ok
+    ;
+        ResultCode = result_code_eof,
+        Result = eof
+    ;
+        ResultCode = result_code_error,
+        make_err_msg(Error, "read failed: ", Msg, !IO),
+        Result = error(io_error(Msg))
+    ).
+
  %---------------------%

      % We communicate results from foreign_procs as separate simple arguments




More information about the reviews mailing list