Re: Misleading docs or implementation of file:read/2 and friends

José Valim <[email protected]>
Newsgroups gmane.comp.lang.erlang.bugs
Message-ID <CAGnRm4LUPC8A=mYUmzjPdeMyz=_aXHL2vvvKmiy9ktjtxUyCaA@mail.gmail.com>
Pinging this thread for feedback.



*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Lead Developer

On Fri, Jul 4, 2014 at 5:10 PM, José Valim <[email protected]>
wrote:

> Hello everyone,
>
> I have found the documentation or implementation file:read/2 to be
> misleading when working with unicode devices in binary mode. I will use
> file:read_line/1 in the examples below but the issue applies to
> file:read/2, file:pread/1 and etc.
>
> $ echo "héllo" > foo
>
> $ erl
> 1> {ok, F} = file:open("foo", [binary, unicode]).
> {ok,<0.34.0>}
> 2> {ok, Bin} = file:read_line(F).
> {ok,<<"héllo\n">>}
> 3> <<Bin/binary, 0>>.
> <<104,233,108,108,111,10, 0>>
>
>
> Not the result is not the one desired because I expected a binary
> containing <<"héllo\n"/utf8>>, or more explicitly, I expected it to contain
> the bytes <<195, 169>> instead of <<233>>. In other words, I got latin1 as
> result. With char lists, we would get "héllo\n" but the function will fail
> for any codepoint > 255.
>
> Note this behaviour also happens if I use file:read_line/1 on any other IO
> device set to unicode (like standard_io).
>
> The trouble I have with the function is that it is aimed to byte-oriented
> but it only really works for latin1 files. If you have a unicode file, the
> behaviour seems to be broken for binaries, and it only works for a limited
> range of codepoints when using char lists.
>
> It is interesting to notice those functions use the old {get_line, Prompt}
> messages which, according to the I/O protocol guide
> <http://www.erlang.org/doc/apps/stdlib/io_protocol.html>, should not
> exist beyond R15B (section 1.3). The same section above suggests to
> translate {get_line, Prompt} to {get_line, latin1, Prompt} which seems to
> be the root cause of the issues above: those functions were never meant to
> work with unicode devices.
>
> Unless I am terribly wrong, I can think of some ways to fix those
> functions:
>
> 1. Keep its dual aspect of returning bytes and/or characters but fix the
> bug when working with unicode. This means the {get_line, Prompt} should
> rather translate to {get_line, EncodingOfTheIODevice, Prompt}
>
> 2. Make them crash if the encoding of the device is not latin1. This means
> we translate {get_line, Prompt} to {get_line, latin1, Prompt} only if the
> encoding of the device is latin1.
>
> 3. Make it always work at the byte level, regardless of the encoding of
> the IO device. This would require assigning new meaning to the {get_line,
> Prompt} message, so I believe it is not going to happen (although it would
> be a useful feature in my opinion).
>
> Given that the original IO messages were never meant to work with unicode,
> maybe 2) is the best way to go here. Both 1) and 2) would require a small
> amendment to the current I/O protocol advice but I would argue it is
> necessary to fix the current limitations/bugs when working with unicode.
>
> *José Valim*
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Lead Developer
>

_______________________________________________
erlang-bugs mailing list
[email protected]
http://erlang.org/mailman/listinfo/erlang-bugs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.