Skip to content

Commit 16b358c

Browse files
author
José Valim
committed
Do not send binread to streams with encoding, closes #7729
1 parent 61d42c2 commit 16b358c

File tree

2 files changed

+187
-141
lines changed

2 files changed

+187
-141
lines changed

lib/elixir/lib/file/stream.ex

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ defmodule File.Stream do
7777
start_fun = fn ->
7878
case :file.open(path, read_modes(modes)) do
7979
{:ok, device} ->
80-
if :trim_bom in modes, do: trim_bom(device), else: device
80+
if :trim_bom in modes, do: trim_bom(device, raw) |> elem(0), else: device
8181

8282
{:error, reason} ->
8383
raise File.Error, reason: reason, action: "stream", path: path
@@ -106,19 +106,24 @@ defmodule File.Stream do
106106
end
107107
end
108108

109-
def count(%{path: path, line_or_bytes: bytes}) do
109+
def count(%{path: path, line_or_bytes: bytes, raw: true, modes: modes}) do
110110
case File.stat(path) do
111111
{:ok, %{size: 0}} ->
112112
{:error, __MODULE__}
113113

114114
{:ok, %{size: size}} ->
115-
{:ok, div(size, bytes) + if(rem(size, bytes) == 0, do: 0, else: 1)}
115+
remainder = if rem(size, bytes) == 0, do: 0, else: 1
116+
{:ok, div(size, bytes) + remainder - count_raw_bom(path, modes)}
116117

117118
{:error, reason} ->
118119
raise File.Error, reason: reason, action: "stream", path: path
119120
end
120121
end
121122

123+
def count(_stream) do
124+
{:error, __MODULE__}
125+
end
126+
122127
def member?(_stream, _term) do
123128
{:error, __MODULE__}
124129
end
@@ -127,10 +132,18 @@ defmodule File.Stream do
127132
{:error, __MODULE__}
128133
end
129134

130-
defp trim_bom(device) do
131-
header = IO.binread(device, 4)
132-
{:ok, _new_pos} = :file.position(device, bom_length(header))
133-
device
135+
defp count_raw_bom(path, modes) do
136+
if :trim_bom in modes do
137+
File.open!(path, read_modes(modes), &(&1 |> trim_bom(true) |> elem(1)))
138+
else
139+
0
140+
end
141+
end
142+
143+
defp trim_bom(device, raw) do
144+
header = if raw, do: IO.binread(device, 4), else: IO.read(device, 1)
145+
{:ok, new_pos} = :file.position(device, bom_length(header))
146+
{device, new_pos}
134147
end
135148

136149
defp bom_length(<<239, 187, 191, _rest::binary>>), do: 3

0 commit comments

Comments
 (0)