Skip to content

Commit 7bcc4b2

Browse files
committed
Use iodata in the internal state of StringIO
1 parent d800e9c commit 7bcc4b2

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

lib/elixir/lib/string_io.ex

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,15 +208,18 @@ defmodule StringIO do
208208

209209
@impl true
210210
def handle_call(:contents, _from, %{input: input, output: output} = state) do
211-
{:reply, {input, output}, state}
211+
# output is built as iodata, and converted before we need to cross the process boundary
212+
output = IO.iodata_to_binary(output)
213+
{:reply, {input, output}, %{state | output: output}}
212214
end
213215

214216
def handle_call(:flush, _from, %{output: output} = state) do
215-
{:reply, output, %{state | output: ""}}
217+
{:reply, IO.iodata_to_binary(output), %{state | output: ""}}
216218
end
217219

218220
def handle_call(:close, _from, %{input: input, output: output} = state) do
219-
{:stop, :normal, {:ok, {input, output}}, state}
221+
output = IO.iodata_to_binary(output)
222+
{:stop, :normal, {:ok, {input, output}}, %{state | output: output}}
220223
end
221224

222225
defp io_request(from, reply_as, req, state) do
@@ -302,7 +305,8 @@ defmodule StringIO do
302305
defp put_chars(encoding, chars, req, state) do
303306
case :unicode.characters_to_binary(chars, encoding, state.encoding) do
304307
string when is_binary(string) ->
305-
{:ok, %{state | output: state.output <> string}}
308+
# we build output as iodata internally
309+
{:ok, %{state | output: [state.output | string]}}
306310

307311
{_, _, _} ->
308312
{{:error, {:no_translation, encoding, state.encoding}}, state}
@@ -455,7 +459,7 @@ defmodule StringIO do
455459
end
456460

457461
defp state_after_read(%{capture_prompt: true, output: output} = state, remainder, prompt, count) do
458-
output = <<output::binary, :binary.copy(IO.chardata_to_string(prompt), count)::binary>>
462+
output = IO.iodata_to_binary([output | :binary.copy(IO.chardata_to_string(prompt), count)])
459463
%{state | input: remainder, output: output}
460464
end
461465

0 commit comments

Comments
 (0)