[m-rev.] for review: putback of 8-bit values to binary input streams
Julien Fischer
jfischer at opturion.com
Fri Oct 5 12:36:11 AEST 2018
For review by anyone.
-------------------------------------
Putback of 8-bit values to binary input streams.
Support direct putback of int8 and uint8 values to binary input streams
instead of via the bottom 8 bits of an int value.
library/io.m:
Add putback_{int8,uint8}/[34].
Add stream type class instances for putback streams binary_input_stream
with int8 and uint8.
tests/hard_coded/Mmakefile:
tests/hard_coded/putback_binary_int8.{m,exp}:
tests/hard_coded/putback_binary_uint8.{m,exp}:
Add tests of the above.
Julien.
diff --git a/library/io.m b/library/io.m
index 20af25a..b3356ff 100644
--- a/library/io.m
+++ b/library/io.m
@@ -1014,6 +1014,20 @@
:- pred putback_byte(io.binary_input_stream::in, int::in, io::di, io::uo)
is det.
+ % As above, but un-reads an int8 instead of a byte represented by
+ % the bottom 8 bits of an int.
+ %
+:- pred putback_int8(int8::in, io::di, io::uo) is det.
+:- pred putback_int8(io.binary_input_stream::in, int8::in, io::di, io::uo)
+ is det.
+
+ % As above, but un-reads a uint8 instead of a byte represented by
+ % the bottom 8 bits of an int.
+ %
+:- pred putback_uint8(uint8::in, io::di, io::uo) is det.
+:- pred putback_uint8(io.binary_input_stream::in, uint8::in, io::di, io::uo)
+ is det.
+
%---------------------------------------------------------------------------%
%
% Binary output predicates.
@@ -1753,6 +1767,8 @@
:- 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).
+:- instance stream.putback(binary_input_stream, uint8, io, io.error).
:- instance stream.seekable(binary_input_stream, io).
%---------------------------------------------------------------------------%
@@ -4480,6 +4496,14 @@ putback_byte(Char, !IO) :-
binary_input_stream(Stream, !IO),
putback_byte(Stream, Char, !IO).
+putback_int8(Int8, !IO) :-
+ binary_input_stream(Stream, !IO),
+ putback_int8(Stream, Int8, !IO).
+
+putback_uint8(UInt8, !IO) :-
+ binary_input_stream(Stream, !IO),
+ putback_uint8(Stream, UInt8, !IO).
+
read(Result, !IO) :-
term_io.read_term(ReadResult, !IO),
get_line_number(LineNumber, !IO),
@@ -7747,6 +7771,39 @@ putback_byte(binary_input_stream(Stream), Character, !IO) :-
}
").
+putback_int8(binary_input_stream(Stream), Int8, !IO) :-
+ UInt8 = uint8.cast_from_int8(Int8),
+ putback_uint8_2(Stream, UInt8, Ok, !IO),
+ (
+ Ok = yes
+ ;
+ Ok = no,
+ throw(io_error("failed to put back int8"))
+ ).
+
+putback_uint8(binary_input_stream(Stream), UInt8, !IO) :-
+ putback_uint8_2(Stream, UInt8, Ok, !IO),
+ (
+ Ok = yes
+ ;
+ Ok = no,
+ throw(io_error("failed to put back uint8"))
+ ).
+
+:- pred putback_uint8_2(stream::in, uint8::in, bool::out, io::di, io::uo) is det.
+:- pragma foreign_proc("C",
+ putback_uint8_2(Stream::in, UInt8::in, Ok::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io,
+ does_not_affect_liveness, no_sharing],
+"
+ MercuryFilePtr mf = Stream;
+ if (MR_UNGETCH(*mf, UInt8) == EOF) {
+ Ok = MR_FALSE;
+ } else {
+ Ok = MR_TRUE;
+ }
+").
+
:- pragma foreign_proc("C#",
read_char_code_2(File::in, Result::out, Char::out, Error::out,
_IO0::di, _IO::uo),
@@ -7829,6 +7886,19 @@ putback_byte(binary_input_stream(Stream), Character, !IO) :-
}
").
+:- pragma foreign_proc("C#",
+ putback_uint8_2(File::in, UInt8::in, Ok::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure],
+"
+ io.MR_MercuryFileStruct mf = File;
+ if (mf.putback == -1) {
+ mf.putback = UInt8;
+ Ok = mr_bool.YES;
+ } else {
+ Ok = mr_bool.NO;
+ }
+").
+
:- pragma foreign_proc("Java",
read_char_code_2(File::in, Result::out, CharCode::out, Error::out,
_IO0::di, _IO::uo),
@@ -7889,6 +7959,14 @@ putback_byte(binary_input_stream(Stream), Character, !IO) :-
Ok = bool.YES;
").
+:- pragma foreign_proc("Java",
+ putback_uint8_2(File::in, UInt8::in, Ok::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
+"
+ ((io.MR_BinaryInputFile) File).ungetc((byte) UInt8);
+ Ok = bool.YES;
+").
+
:- pragma foreign_proc("Erlang",
read_char_code_2(Stream::in, Result::out, Char::out, Error::out,
_IO0::di, _IO::uo),
@@ -7949,6 +8027,14 @@ putback_byte(binary_input_stream(Stream), Character, !IO) :-
Ok = {yes}
").
+:- pragma foreign_proc("Erlang",
+ putback_uint8_2(File::in, UInt8::in, Ok::out, _IO0::di, _IO::uo),
+ [will_not_call_mercury, promise_pure, tabled_for_io],
+"
+ mercury__io:mercury_putback(File, UInt8),
+ Ok = {yes}
+").
+
%---------------------------------------------------------------------------%
%
% Output predicates (with output to mercury_current_text_output).
@@ -12636,6 +12722,18 @@ result_to_stream_result(error(Error)) = error(Error).
pred(unget/4) is putback_byte
].
+:- instance stream.putback(binary_input_stream, int8, io, io.error)
+ where
+[
+ pred(unget/4) is putback_int8
+].
+
+:- instance stream.putback(binary_input_stream, uint8, io, io.error)
+ where
+[
+ pred(unget/4) is putback_uint8
+].
+
:- instance stream.seekable(binary_input_stream, io)
where
[
diff --git a/tests/hard_coded/Mmakefile b/tests/hard_coded/Mmakefile
index 7c6e8cb..619f71f 100644
--- a/tests/hard_coded/Mmakefile
+++ b/tests/hard_coded/Mmakefile
@@ -287,6 +287,8 @@ ORDINARY_PROGS = \
promise_eqv_solns_typeclasses \
psqueue_test \
pure_mutable \
+ putback_binary_int8 \
+ putback_binary_uint8 \
puzzle_detism_bug \
qual_adv_test \
qual_basic_test \
diff --git a/tests/hard_coded/putback_binary_int8.exp b/tests/hard_coded/putback_binary_int8.exp
index e69de29..5eeffc2 100644
--- a/tests/hard_coded/putback_binary_int8.exp
+++ b/tests/hard_coded/putback_binary_int8.exp
@@ -0,0 +1,32 @@
+Position: 0
+
+Read: 97i8
+Position: 1
+
+Seek: +1
+Position: 2
+
+Read: 99i8
+Position: 3
+
+Put back: -128i8
+Position: 2
+
+Read: -128i8
+Position: 3
+
+Read: 10i8
+Position: 4
+
+Read: eof
+Position: 4
+
+Put back: 127i8
+Position: 3
+
+Seek: -2
+Position: 1
+
+Read: 98i8
+Position: 2
+
diff --git a/tests/hard_coded/putback_binary_int8.m b/tests/hard_coded/putback_binary_int8.m
index e69de29..0fd5146 100644
--- a/tests/hard_coded/putback_binary_int8.m
+++ b/tests/hard_coded/putback_binary_int8.m
@@ -0,0 +1,88 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+%
+% Test putback for int8 values with binary streams.
+%
+%---------------------------------------------------------------------------%
+
+:- module putback_binary_int8.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module char.
+:- import_module int.
+:- import_module list.
+:- import_module require.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+ io.open_binary_input("stream_putback.data", OpenRes, !IO),
+ (
+ OpenRes = ok(Stream),
+ print_position(Stream, !IO), % pos 0
+ print_read_byte(Stream, !IO), % pos 1
+ print_relseek(Stream, 1, !IO), % pos 2
+ print_read_byte(Stream, !IO), % pos 3
+ print_putback(Stream, -128i8, !IO), % pos 2
+ print_read_byte(Stream, !IO), % -128i8 pos 3
+ print_read_byte(Stream, !IO), % 10i8 (\n), pos 4
+ print_read_byte(Stream, !IO), % eof, pos 4
+ print_putback(Stream, 127i8, !IO), % pos 3
+ print_relseek(Stream, -2, !IO), % pos 1; pushback dropped
+ print_read_byte(Stream, !IO), % b, pos 2
+ io.close_binary_input(Stream, !IO)
+ ;
+ OpenRes = error(Error),
+ error(io.error_message(Error))
+ ).
+
+:- pred print_read_byte(io.binary_input_stream::in, io::di, io::uo) is det.
+
+print_read_byte(Stream, !IO) :-
+ io.read_binary_int8(Stream, ReadRes, !IO),
+ (
+ ReadRes = ok(Int8),
+ io.write_string("Read: ", !IO),
+ io.write_line(Int8, !IO)
+ ;
+ ReadRes = eof,
+ io.write_string("Read: eof\n", !IO)
+ ;
+ ReadRes = error(Error),
+ error(io.error_message(Error))
+ ),
+ print_position(Stream, !IO).
+
+:- pred print_putback(io.binary_input_stream::in, int8::in, io::di, io::uo)
+ is det.
+
+print_putback(Stream, Int8, !IO) :-
+ io.putback_int8(Stream, Int8, !IO),
+ io.write_string("Put back: ", !IO),
+ io.write_line(Int8, !IO),
+ print_position(Stream, !IO).
+
+:- pred print_relseek(io.binary_input_stream::in, int::in, io::di, io::uo)
+ is det.
+
+print_relseek(Stream, Offset, !IO) :-
+ io.seek_binary_input(Stream, cur, Offset, !IO),
+ io.format("Seek: %+d\n", [i(Offset)], !IO),
+ print_position(Stream, !IO).
+
+:- pred print_position(io.binary_input_stream::in, io::di, io::uo) is det.
+
+print_position(Stream, !IO) :-
+ io.binary_input_stream_offset(Stream, Offset, !IO),
+ io.format("Position: %d\n\n", [i(Offset)], !IO).
diff --git a/tests/hard_coded/putback_binary_uint8.m b/tests/hard_coded/putback_binary_uint8.m
index e69de29..b6e2489 100644
--- a/tests/hard_coded/putback_binary_uint8.m
+++ b/tests/hard_coded/putback_binary_uint8.m
@@ -0,0 +1,88 @@
+%---------------------------------------------------------------------------%
+% vim: ts=4 sw=4 et ft=mercury
+%---------------------------------------------------------------------------%
+%
+% Test putback for uint8 values with binary streams.
+%
+%---------------------------------------------------------------------------%
+
+:- module putback_binary_uint8.
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module char.
+:- import_module int.
+:- import_module list.
+:- import_module require.
+:- import_module string.
+
+%---------------------------------------------------------------------------%
+
+main(!IO) :-
+ io.open_binary_input("stream_putback.data", OpenRes, !IO),
+ (
+ OpenRes = ok(Stream),
+ print_position(Stream, !IO), % pos 0
+ print_read_byte(Stream, !IO), % pos 1
+ print_relseek(Stream, 1, !IO), % pos 2
+ print_read_byte(Stream, !IO), % pos 3
+ print_putback(Stream, 128u8, !IO), % pos 2
+ print_read_byte(Stream, !IO), % 128u8 pos 3
+ print_read_byte(Stream, !IO), % 10u8 (\n), pos 4
+ print_read_byte(Stream, !IO), % eof, pos 4
+ print_putback(Stream, 255u8, !IO), % pos 3
+ print_relseek(Stream, -2, !IO), % pos 1; pushback dropped
+ print_read_byte(Stream, !IO), % b, pos 2
+ io.close_binary_input(Stream, !IO)
+ ;
+ OpenRes = error(Error),
+ error(io.error_message(Error))
+ ).
+
+:- pred print_read_byte(io.binary_input_stream::in, io::di, io::uo) is det.
+
+print_read_byte(Stream, !IO) :-
+ io.read_binary_uint8(Stream, ReadRes, !IO),
+ (
+ ReadRes = ok(UInt8),
+ io.write_string("Read: ", !IO),
+ io.write_line(UInt8, !IO)
+ ;
+ ReadRes = eof,
+ io.write_string("Read: eof\n", !IO)
+ ;
+ ReadRes = error(Error),
+ error(io.error_message(Error))
+ ),
+ print_position(Stream, !IO).
+
+:- pred print_putback(io.binary_input_stream::in, uint8::in, io::di, io::uo)
+ is det.
+
+print_putback(Stream, UInt8, !IO) :-
+ io.putback_uint8(Stream, UInt8, !IO),
+ io.write_string("Put back: ", !IO),
+ io.write_line(UInt8, !IO),
+ print_position(Stream, !IO).
+
+:- pred print_relseek(io.binary_input_stream::in, int::in, io::di, io::uo)
+ is det.
+
+print_relseek(Stream, Offset, !IO) :-
+ io.seek_binary_input(Stream, cur, Offset, !IO),
+ io.format("Seek: %+d\n", [i(Offset)], !IO),
+ print_position(Stream, !IO).
+
+:- pred print_position(io.binary_input_stream::in, io::di, io::uo) is det.
+
+print_position(Stream, !IO) :-
+ io.binary_input_stream_offset(Stream, Offset, !IO),
+ io.format("Position: %d\n\n", [i(Offset)], !IO).
More information about the reviews
mailing list