implement IO.(bin)read which accept :all

IO.(bin)read(dev, `:all`) reads all contents from device

Signed-off-by: José Valim <jose.valim@plataformatec.com.br>
This commit is contained in:
Joe-noh
2014-07-08 11:39:18 +02:00
committed by José Valim
parent 597d90b326
commit 7c12cf029c
2 changed files with 53 additions and 4 deletions
+32 -4
View File
@@ -44,7 +44,9 @@ defmodule IO do
@doc """
Reads `count` characters from the IO device or until
the end of the line if `:line` is given. It returns:
the end of the line if `:line` is given. If `:all` is
given, returns empty string instead of `:eof`.
It returns:
* `data` - the input characters
@@ -54,9 +56,21 @@ defmodule IO do
for instance, `{:error, :estale}` if reading from an
NFS volume
"""
@spec read(device, :line | non_neg_integer) :: chardata | nodata
@spec read(device, :all | :line | non_neg_integer) :: chardata | nodata
def read(device \\ group_leader, chars_or_line)
def read(device, :all) do
do_read_all(map_dev(device), "")
end
defp do_read_all(mapped_dev, acc) do
case :io.get_line(mapped_dev, "") do
line when is_binary(line) -> do_read_all(mapped_dev, acc <> line)
:eof -> acc
other -> other
end
end
def read(device, :line) do
:io.get_line(map_dev(device), '')
end
@@ -67,7 +81,9 @@ defmodule IO do
@doc """
Reads `count` bytes from the IO device or until
the end of the line if `:line` is given. It returns:
the end of the line if `:line` is given. If `:all` is
given, returns empty string instead of `:eof`.
It returns:
* `data` - the input characters
@@ -80,9 +96,21 @@ defmodule IO do
Note: do not use this function on IO devices in unicode mode
as it will return the wrong result.
"""
@spec binread(device, :line | non_neg_integer) :: iodata | nodata
@spec binread(device, :all | :line | non_neg_integer) :: iodata | nodata
def binread(device \\ group_leader, chars_or_line)
def binread(device, :all) do
do_binread_all(map_dev(device), "")
end
defp do_binread_all(mapped_dev, acc) do
case :file.read_line(mapped_dev) do
{:ok, data} -> do_binread_all(mapped_dev, acc <> data)
:eof -> acc
other -> other
end
end
def binread(device, :line) do
case :file.read_line(map_dev(device)) do
{:ok, data} -> data
+21
View File
@@ -58,6 +58,20 @@ defmodule IOTest do
assert File.close(file) == :ok
end
test :readall do
{:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__))
assert "FOO\n" == IO.read(file, :all)
assert "" == IO.read(file, :all)
assert File.close(file) == :ok
end
test :readall_with_utf8_and_binary do
{:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__), [:utf8])
assert "Русский\n日\n" == IO.read(file, :all)
assert "" == IO.read(file, :all)
assert File.close(file) == :ok
end
test :readline do
{:ok, file} = File.open(Path.expand('fixtures/file.txt', __DIR__))
assert "FOO\n" == IO.read(file, :line)
@@ -72,6 +86,13 @@ defmodule IOTest do
assert File.close(file) == :ok
end
test :binreadall do
{:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__))
assert "Русский\n日\n" == IO.binread(file, :all)
assert "" == IO.binread(file, :all)
assert File.close(file) == :ok
end
test :binreadline do
{:ok, file} = File.open(Path.expand('fixtures/utf8.txt', __DIR__))
assert "Русский\n" == IO.binread(file, :line)