Current section

Files

Jump to
quickbeam lib quickbeam vm runtime web binary_data.ex
Raw

lib/quickbeam/vm/runtime/web/binary_data.ex

defmodule QuickBEAM.VM.Runtime.Web.BinaryData do
@moduledoc "Helpers for exposing BEAM binaries as Web binary JS objects."
alias QuickBEAM.VM.Heap
alias QuickBEAM.VM.Runtime.Constructors
@doc "Constructs a JavaScript `Uint8Array` from a binary."
def uint8_array(bytes) when is_binary(bytes) do
bytes
|> :binary.bin_to_list()
|> uint8_array()
end
def uint8_array(bytes) when is_list(bytes) do
Constructors.construct("Uint8Array", [bytes], fn -> Heap.wrap(bytes) end)
end
def typed_array_bytes(map) when is_map(map) do
case Map.get(map, "buffer") do
{:obj, buf_ref} ->
case Heap.get_obj(buf_ref, %{}) do
buffer_map when is_map(buffer_map) ->
slice_buffer_bytes(buffer_map, map)
_ ->
Map.get(map, "__buffer__", <<>>)
end
_ ->
Map.get(map, "__buffer__", <<>>)
end
end
@doc "Constructs a JavaScript `ArrayBuffer` containing `bytes`."
def array_buffer(bytes) when is_binary(bytes) do
byte_len = byte_size(bytes)
Constructors.construct(
"ArrayBuffer",
[byte_len],
fn -> Heap.wrap(%{"__buffer__" => bytes, "byteLength" => byte_len}) end,
&Map.put(&1, "__buffer__", bytes)
)
end
defp slice_buffer_bytes(buffer_map, view_map) do
ab_buf = Map.get(buffer_map, "__buffer__", <<>>)
offset = Map.get(view_map, "byteOffset", 0)
byte_len = Map.get(view_map, "byteLength", 0)
if byte_size(ab_buf) >= offset + byte_len and byte_len > 0 do
binary_part(ab_buf, offset, byte_len)
else
Map.get(view_map, "__buffer__", <<>>)
end
end
end