Skip to content

Instantly share code, notes, and snippets.

@YannickFricke
Created August 13, 2025 15:12
Show Gist options
  • Select an option

  • Save YannickFricke/3c9b54de7634cf220bd8572f843bf025 to your computer and use it in GitHub Desktop.

Select an option

Save YannickFricke/3c9b54de7634cf220bd8572f843bf025 to your computer and use it in GitHub Desktop.
defmodule MovEx.BufferedReader do
@moduledoc false
@enforce_keys ~w(source buffer chunk_size)a
defstruct ~w(source buffer chunk_size)a
@type t() :: %__MODULE__{
source: Stream.t(),
buffer: binary(),
chunk_size: pos_integer()
}
def new(source, chunk_size \\ 1024), do: %__MODULE__{source: source, buffer: <<>>, chunk_size: chunk_size}
def read(buffered_reader, amount_of_bytes, processed_byte_length \\ false)
def read(%__MODULE__{buffer: buffer}, amount_of_bytes, true) when byte_size(buffer) < amount_of_bytes,
do: {:error, :eof}
def read(%__MODULE__{buffer: buffer, source: source} = buffered_reader, amount_of_bytes, false)
when byte_size(buffer) < amount_of_bytes do
amount_of_chunks = ceil(amount_of_bytes / buffered_reader.chunk_size)
new_data =
source
|> Stream.take(amount_of_chunks)
|> Enum.into(<<>>)
read(
%{
buffered_reader
| buffer: buffer <> new_data,
source: Stream.drop(source, amount_of_chunks)
},
amount_of_bytes,
true
)
end
def read(%__MODULE__{buffer: buffer} = buffered_reader, amount_of_bytes, _processed_byte_length) do
<<data::binary-size(amount_of_bytes), rest::bitstring>> = buffer
{:ok, data, %{buffered_reader | buffer: rest}}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment