[m-rev.] for review: add write_binary_utf8_string

Peter Wang novalazy at gmail.com
Thu Apr 7 11:26:39 AEST 2022


On Thu, 07 Apr 2022 10:38:02 +1000 Julien Fischer <jfischer at opturion.com> wrote:
> 
> diff --git a/NEWS b/NEWS
> index 3e03928..507eebd 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -68,6 +68,11 @@ The following obsolete predicates have been removed:
> 
>   ### Changes to the `io` module
> 
> +* The following predicates have been added:
> +
> +    - pred `write_binary_utf8_string/3`
> +    - pred `write_binary_utf8_string/4`
> +
>   * The following obsolete predicates have been removed:
> 
>       - pred `see/3`                  (replacement: `prolog.see/3`)
> diff --git a/library/io.m b/library/io.m
> index 29dff2b..54667b5 100644
> --- a/library/io.m
> +++ b/library/io.m
> @@ -837,6 +837,16 @@
>   :- pred write_binary_uint64_be(io.binary_output_stream::in, uint64::in,
>       io::di, io::uo) is det.
> 
> +%---------------------%
> +
> +    % Write the UTF-8 encoding of a string to the current binary output stream
> +    % or the specified binary output stream. If the given string is not
> +    % well-formed, then the behaviour is implementation dependent.
> +    %
> +:- pred write_binary_utf8_string(string::in, io::di, io::uo) is det.
> +:- pred write_binary_utf8_string(io.binary_output_stream::in, string::in,
> +    io::di, io::uo) is det.
> +

Or write_binary_string_utf8, in line with the pattern
write_binary_<TYPE><SUFFIX>?

> @@ -1147,6 +1150,50 @@ do_write_float(Stream, Float, Error, !IO) :-
>   ").
> 
>   %---------------------------------------------------------------------------%
> +
> +:- pragma foreign_proc("C",
> +    do_write_binary_utf8_string(Stream::in, String::in, Error::out,
> +        _IO0::di, _IO::uo),
> +    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
> +"
> +    size_t len = strlen(String);
> +    if (MR_WRITE(*Stream, (unsigned char *) String, len)) {

Check the result is != len.

> +        Error = errno;
> +    } else {
> +        Error = 0;
> +    }
> +").
> +
> +:- pragma foreign_proc("C#",
> +    do_write_binary_utf8_string(Stream::in, String::in, Error::out,
> +        _IO0::di, _IO::uo),
> +    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
> +"
> +    byte[] bytes = mercury.io__stream_ops.text_encoding.GetBytes(String);
> +    try {
> +        Stream.stream.Write(bytes, 0, bytes.Length);
> +        Error = null;
> +    } catch (System.Exception e) {
> +        Error = e;
> +    }
> +").
> +
> +:- pragma foreign_proc("Java",
> +    do_write_binary_utf8_string(Stream::in, String::in, Error::out,
> +        _IO0::di, _IO::uo),
> +    [will_not_call_mercury, promise_pure, thread_safe, tabled_for_io],
> +"
> +    byte[] bytes = String.getBytes(java.nio.charset.StandardCharsets.UTF_8);
> +    try {
> +        ((jmercury.io__stream_ops.MR_BinaryOutputFile) Stream).write(
> +            bytes, 0, bytes.length);
> +        Error = null;
> +    } catch (java.io.IOException e) {
> +        Error = e;
> +    }
> +").
> +

That looks fine. (I had a quick look around for something more efficient
but nothing obvious came up.)

> diff --git a/tests/hard_coded/write_binary_utf8.m b/tests/hard_coded/write_binary_utf8.m
> index e69de29..0ca6e27 100644
> --- a/tests/hard_coded/write_binary_utf8.m
> +++ b/tests/hard_coded/write_binary_utf8.m
...
> +%---------------------------------------------------------------------------%
> +
> +main(!IO) :-
> +    io.open_binary_output(test_file, OpenOutResult, !IO),
> +    (
> +        OpenOutResult = ok(Out),
> +        output_test_strings(Out, !IO),
> +        io.close_binary_output(Out, !IO),
> +        read_and_print_bytes(!IO),

Minor: make read_and_print_bytes take the file name as an argument.

Peter


More information about the reviews mailing list